Добавлен таргет проект для PY32F002A
This commit is contained in:
559
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal.c
Normal file
559
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal.c
Normal file
@@ -0,0 +1,559 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal.c
|
||||
* @author MCU Application Team
|
||||
* @brief HAL module driver.
|
||||
* This is the common part of the HAL initialization
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The common HAL driver contains a set of generic and common APIs that can be
|
||||
used by the PPP peripheral drivers and the user to start using the HAL.
|
||||
[..]
|
||||
The HAL contains two APIs categories:
|
||||
(+) Common HAL APIs
|
||||
(+) Services HAL APIs
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL
|
||||
* @brief HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Private_Constants HAL Private Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief PY32F0xx HAL Driver version number
|
||||
*/
|
||||
#define __PY32F0xx_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
|
||||
#define __PY32F0xx_HAL_VERSION_SUB1 (0x03U) /*!< [23:16] sub1 version */
|
||||
#define __PY32F0xx_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
|
||||
#define __PY32F0xx_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
|
||||
#define __PY32F0xx_HAL_VERSION ((__PY32F0xx_HAL_VERSION_MAIN << 24U)\
|
||||
|(__PY32F0xx_HAL_VERSION_SUB1 << 16U)\
|
||||
|(__PY32F0xx_HAL_VERSION_SUB2 << 8U )\
|
||||
|(__PY32F0xx_HAL_VERSION_RC))
|
||||
|
||||
#if defined(VREFBUF)
|
||||
#define VREFBUF_TIMEOUT_VALUE 10U /*!< 10 ms */
|
||||
#endif /* VREFBUF */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Exported variables ---------------------------------------------------------*/
|
||||
/** @defgroup HAL_Exported_Variables HAL Exported Variables
|
||||
* @{
|
||||
*/
|
||||
__IO uint32_t uwTick;
|
||||
uint32_t uwTickPrio = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
|
||||
uint32_t uwTickFreq = HAL_TICK_FREQ_DEFAULT; /* 1KHz */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group1
|
||||
* @brief HAL Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Initialization and Configuration functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the Flash interface the NVIC allocation and initial time base
|
||||
clock configuration.
|
||||
(+) De-initialize common part of the HAL.
|
||||
(+) Configure the time base source to have 1ms time base with a dedicated
|
||||
Tick interrupt priority.
|
||||
(++) SysTick timer is used by default as source of time base, but user
|
||||
can eventually implement his proper time base source (a general purpose
|
||||
timer for example or other time source), keeping in mind that Time base
|
||||
duration should be kept 1ms since PPP_TIMEOUT_VALUEs are defined and
|
||||
handled in milliseconds basis.
|
||||
(++) Time base configuration function (HAL_InitTick ()) is called automatically
|
||||
at the beginning of the program after reset by HAL_Init() or at any time
|
||||
when clock is configured, by HAL_RCC_ClockConfig().
|
||||
(++) Source of time base is configured to generate interrupts at regular
|
||||
time intervals. Care must be taken if HAL_Delay() is called from a
|
||||
peripheral ISR process, the Tick interrupt line must have higher priority
|
||||
(numerically lower) than the peripheral interrupt. Otherwise the caller
|
||||
ISR process will be blocked.
|
||||
(++) functions affecting time base configurations are declared as __weak
|
||||
to make override possible in case of other implementations in user file.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure the Flash prefetch and the Instruction cache,
|
||||
* the time base source, NVIC and any required global low level hardware
|
||||
* by calling the HAL_MspInit() callback function to be optionally defined in user file
|
||||
* PY32F0xx_hal_msp.c.
|
||||
*
|
||||
* @note HAL_Init() function is called at the beginning of program after reset and before
|
||||
* the clock configuration.
|
||||
*
|
||||
* @note In the default implementation the System Timer (Systick) is used as source of time base.
|
||||
* The Systick configuration is based on HSI clock, as HSI is the clock
|
||||
* used after a system Reset.
|
||||
* Once done, time base tick starts incrementing: the tick variable counter is incremented
|
||||
* each 1ms in the SysTick_Handler() interrupt handler.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_Init(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Configure Flash prefetch, Instruction cache */
|
||||
/* Default configuration at reset is: */
|
||||
/* - Prefetch disabled */
|
||||
/* - Instruction cache enabled */
|
||||
|
||||
/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */
|
||||
if (HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Init the low level hardware */
|
||||
HAL_MspInit();
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function de-Initializes common part of the HAL and stops the source of time base.
|
||||
* @note This function is optional.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DeInit(void)
|
||||
{
|
||||
/* Reset of all peripherals */
|
||||
__HAL_RCC_APB1_FORCE_RESET();
|
||||
__HAL_RCC_APB1_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_APB2_FORCE_RESET();
|
||||
__HAL_RCC_APB2_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_AHB_FORCE_RESET();
|
||||
__HAL_RCC_AHB_RELEASE_RESET();
|
||||
|
||||
__HAL_RCC_IOP_FORCE_RESET();
|
||||
__HAL_RCC_IOP_RELEASE_RESET();
|
||||
|
||||
/* De-Init the low level hardware */
|
||||
HAL_MspDeInit();
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the MSP.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_MspInit(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the MSP.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_MspDeInit(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures the source of the time base:
|
||||
* The time source is configured to have 1ms time base with a dedicated
|
||||
* Tick interrupt priority.
|
||||
* @note This function is called automatically at the beginning of program after
|
||||
* reset by HAL_Init() or at any time when clock is reconfigured by HAL_RCC_ClockConfig().
|
||||
* @note In the default implementation, SysTick timer is the source of time base.
|
||||
* It is used to generate interrupts at regular time intervals.
|
||||
* Care must be taken if HAL_Delay() is called from a peripheral ISR process,
|
||||
* The SysTick interrupt must have higher priority (numerically lower)
|
||||
* than the peripheral interrupt. Otherwise the caller ISR process will be blocked.
|
||||
* The function is declared as __weak to be overwritten in case of other
|
||||
* implementation in user file.
|
||||
* @param TickPriority Tick interrupt priority.
|
||||
* @retval HAL status
|
||||
*/
|
||||
__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (uwTickFreq != 0U)
|
||||
{
|
||||
/*Configure the SysTick to have interrupt in 1ms time basis*/
|
||||
if (HAL_SYSTICK_Config(SystemCoreClock / (1000U /uwTickFreq)) == 0U)
|
||||
{
|
||||
/* Configure the SysTick IRQ priority */
|
||||
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
|
||||
{
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0U);
|
||||
uwTickPrio = TickPriority;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group2
|
||||
* @brief HAL Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Control functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Provide a tick value in millisecond
|
||||
(+) Provide a blocking delay in millisecond
|
||||
(+) Suspend the time base source interrupt
|
||||
(+) Resume the time base source interrupt
|
||||
(+) Get the HAL API driver version
|
||||
(+) Get the device identifier
|
||||
(+) Get the device revision identifier
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function is called to increment a global variable "uwTick"
|
||||
* used as application time base.
|
||||
* @note In the default implementation, this variable is incremented each 1ms
|
||||
* in SysTick ISR.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IncTick(void)
|
||||
{
|
||||
uwTick += uwTickFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provides a tick value in millisecond.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval tick value
|
||||
*/
|
||||
__weak uint32_t HAL_GetTick(void)
|
||||
{
|
||||
return uwTick;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function returns a tick priority.
|
||||
* @retval tick priority
|
||||
*/
|
||||
uint32_t HAL_GetTickPrio(void)
|
||||
{
|
||||
return uwTickPrio;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set new tick Freq.
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_SetTickFreq(uint32_t Freq)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
assert_param(IS_TICKFREQ(Freq));
|
||||
|
||||
if (uwTickFreq != Freq)
|
||||
{
|
||||
/* Apply the new tick Freq */
|
||||
status = HAL_InitTick(uwTickPrio);
|
||||
if (status == HAL_OK)
|
||||
{
|
||||
uwTickFreq = Freq;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief return tick frequency.
|
||||
* @retval tick period in Hz
|
||||
*/
|
||||
uint32_t HAL_GetTickFreq(void)
|
||||
{
|
||||
return uwTickFreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function provides minimum delay (in milliseconds) based
|
||||
* on variable incremented.
|
||||
* @note In the default implementation , SysTick timer is the source of time base.
|
||||
* It is used to generate interrupts at regular time intervals where uwTick
|
||||
* is incremented.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @param Delay specifies the delay time length, in milliseconds.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_Delay(uint32_t Delay)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
uint32_t wait = Delay;
|
||||
|
||||
/* Add a freq to guarantee minimum wait */
|
||||
if (wait < HAL_MAX_DELAY)
|
||||
{
|
||||
wait += (uint32_t)(uwTickFreq);
|
||||
}
|
||||
|
||||
while ((HAL_GetTick() - tickstart) < wait)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Suspend Tick increment.
|
||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||
* used to generate interrupts at regular time intervals. Once HAL_SuspendTick()
|
||||
* is called, the SysTick interrupt will be disabled and so Tick increment
|
||||
* is suspended.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_SuspendTick(void)
|
||||
{
|
||||
/* Disable SysTick Interrupt */
|
||||
CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resume Tick increment.
|
||||
* @note In the default implementation , SysTick timer is the source of time base. It is
|
||||
* used to generate interrupts at regular time intervals. Once HAL_ResumeTick()
|
||||
* is called, the SysTick interrupt will be enabled and so Tick increment
|
||||
* is resumed.
|
||||
* @note This function is declared as __weak to be overwritten in case of other
|
||||
* implementations in user file.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ResumeTick(void)
|
||||
{
|
||||
/* Enable SysTick Interrupt */
|
||||
SET_BIT(SysTick->CTRL, SysTick_CTRL_TICKINT_Msk);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the HAL revision
|
||||
* @retval version : 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t HAL_GetHalVersion(void)
|
||||
{
|
||||
return __PY32F0xx_HAL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device revision identifier.
|
||||
* @retval Device revision identifier
|
||||
*/
|
||||
uint32_t HAL_GetREVID(void)
|
||||
{
|
||||
return ((DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device identifier.
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetDEVID(void)
|
||||
{
|
||||
return ((DBGMCU->IDCODE) & DBGMCU_IDCODE_DEV_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns first word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw0(void)
|
||||
{
|
||||
return (READ_REG(*((uint32_t *)UID_BASE)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns second word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw1(void)
|
||||
{
|
||||
return (READ_REG(*((uint32_t *)(UID_BASE + 4U))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns third word of the unique device identifier (UID based on 96 bits)
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetUIDw2(void)
|
||||
{
|
||||
return (READ_REG(*((uint32_t *)(UID_BASE + 8U))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group3
|
||||
* @brief HAL Debug functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL Debug functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Enable/Disable Debug module during STOP mode
|
||||
(+) Enable/Disable Debug module during STANDBY mode
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STOP mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGMCUStopMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STOP mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGMCUStopMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup HAL_Exported_Functions_Group4
|
||||
* @brief SYSCFG configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### HAL SYSCFG configuration functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Enable/Disable Pin remap
|
||||
(+) Configure the Voltage reference buffer
|
||||
(+) Enable/Disable the Voltage reference buffer
|
||||
(+) Enable/Disable the I/O analog switch voltage booster
|
||||
(+) Enable/Disable dead battery behavior(*)
|
||||
(+) Configure Clamping Diode on specific pins(*)
|
||||
(*) Feature not available on all devices
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
void HAL_SYSCFG_DMA_Req(uint32_t Requset)
|
||||
{
|
||||
/* Check the parameter */
|
||||
|
||||
SET_BIT(SYSCFG->CFGR3, Requset);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
2339
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_adc.c
Normal file
2339
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_adc.c
Normal file
@@ -0,0 +1,2339 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_adc.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides firmware functions to manage the following
|
||||
* functionalities of the Analog to Digital Convertor (ADC)
|
||||
* peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* ++ Initialization and Configuration of ADC
|
||||
* + Operation functions
|
||||
* ++ Start, stop, get result of conversions of regular
|
||||
* group, using 3 possible modes: polling, interruption or DMA.
|
||||
* + Control functions
|
||||
* ++ Channels configuration on regular group
|
||||
* ++ Analog Watchdog configuration
|
||||
* + State functions
|
||||
* ++ ADC state machine management
|
||||
* ++ Interrupts and flags management
|
||||
* Other functions (extended functions) are available in file
|
||||
* "py32f0xx_hal_adc_ex.c".
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### ADC peripheral features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) 12-bit, 10-bit, 8-bit or 6-bit configurable resolution
|
||||
|
||||
(+) Interrupt generation at the end of regular conversion and in case of
|
||||
analog watchdog or overrun events.
|
||||
|
||||
(+) Single and continuous conversion modes.
|
||||
|
||||
(+) Scan mode for conversion of several channels sequentially.
|
||||
|
||||
(+) Data alignment with in-built data coherency.
|
||||
|
||||
(+) Programmable sampling time (common for all channels)
|
||||
|
||||
(+) ADC conversion of regular group.
|
||||
|
||||
(+) External trigger (timer or EXTI) with configurable polarity
|
||||
|
||||
(+) DMA request generation for transfer of conversions data of regular group.
|
||||
|
||||
(+) ADC calibration
|
||||
|
||||
(+) ADC supply requirements: 2.4 V to 3.6 V at full speed and down to 1.8 V at
|
||||
slower speed.
|
||||
|
||||
(+) ADC input range: from Vref- (connected to Vssa) to Vref+ (connected to
|
||||
Vdda or to an external voltage reference).
|
||||
|
||||
******************************************************************************
|
||||
* @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 PY32F0xxHAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ADC ADC
|
||||
* @brief ADC HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup ADC_Private_Constants ADC Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Fixed timeout values for ADC calibration, enable settling time, disable */
|
||||
/* settling time. */
|
||||
/* Values defined to be higher than worst cases: low clock frequency, */
|
||||
/* maximum prescaler. */
|
||||
/* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
|
||||
/* prescaler 4, sampling time 7.5 ADC clock cycles, resolution 12 bits. */
|
||||
/* Unit: ms */
|
||||
#define ADC_ENABLE_TIMEOUT ( 2U)
|
||||
#define ADC_DISABLE_TIMEOUT ( 2U)
|
||||
#define ADC_STOP_CONVERSION_TIMEOUT ( 2U)
|
||||
|
||||
/* Delay for ADC stabilization time. */
|
||||
/* Maximum delay is 1us (refer to device datasheet, parameter tSTAB). */
|
||||
/* Unit: us */
|
||||
#define ADC_STAB_DELAY_US ( 1U)
|
||||
|
||||
/* Delay for temperature sensor stabilization time. */
|
||||
/* Maximum delay is 10us (refer to device datasheet, parameter tSTART). */
|
||||
/* Unit: us */
|
||||
#define ADC_TEMPSENSOR_DELAY_US ( 10U)
|
||||
|
||||
/* Fixed timeout values for ADC calibration, enable settling time, disable */
|
||||
/* settling time. */
|
||||
/* Values defined to be higher than worst cases: low clock frequency, */
|
||||
/* maximum prescaler. */
|
||||
/* Ex of profile low frequency : Clock source at 0.1 MHz, ADC clock */
|
||||
/* prescaler 4. */
|
||||
/* Unit: ms */
|
||||
#define ADC_CALIBRATION_TIMEOUT ( 2U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup ADC_Private_Functions ADC Private Functions
|
||||
* @{
|
||||
*/
|
||||
static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc);
|
||||
static HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef* hadc);
|
||||
static HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef* hadc);
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma);
|
||||
static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma);
|
||||
static void ADC_DMAError(DMA_HandleTypeDef *hdma);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup ADC_Exported_Functions ADC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Exported_Functions_Group1 Initialization/de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize and configure the ADC.
|
||||
(+) De-initialize the ADC
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the ADC peripheral and regular group according to
|
||||
* parameters specified in structure "ADC_InitTypeDef".
|
||||
* @note As prerequisite, ADC clock must be configured at RCC top level
|
||||
* depending on both possible clock sources: APB clock or HSI clock.
|
||||
* See commented example code below that can be copied and uncommented
|
||||
* into HAL_ADC_MspInit().
|
||||
* @note Possibility to update parameters on the fly:
|
||||
* This function initializes the ADC MSP (HAL_ADC_MspInit()) only when
|
||||
* coming from ADC state reset. Following calls to this function can
|
||||
* be used to reconfigure some parameters of ADC_InitTypeDef
|
||||
* structure on the fly, without modifying MSP configuration. If ADC
|
||||
* MSP has to be modified again, HAL_ADC_DeInit() must be called
|
||||
* before HAL_ADC_Init().
|
||||
* The setting of these parameters is conditioned to ADC state.
|
||||
* For parameters constraints, see comments of structure
|
||||
* "ADC_InitTypeDef".
|
||||
* @note This function configures the ADC within 2 scopes: scope of entire
|
||||
* ADC and scope of regular group. For parameters details, see comments
|
||||
* of structure "ADC_InitTypeDef".
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
uint32_t tmpCFGR1 = 0U;
|
||||
|
||||
/* Check ADC handle */
|
||||
if(hadc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
assert_param(IS_ADC_CLOCKPRESCALER(hadc->Init.ClockPrescaler));
|
||||
assert_param(IS_ADC_RESOLUTION(hadc->Init.Resolution));
|
||||
assert_param(IS_ADC_DATA_ALIGN(hadc->Init.DataAlign));
|
||||
assert_param(IS_ADC_SCAN_MODE(hadc->Init.ScanConvMode));
|
||||
assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
|
||||
assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DiscontinuousConvMode));
|
||||
assert_param(IS_ADC_EXTTRIG_EDGE(hadc->Init.ExternalTrigConvEdge));
|
||||
assert_param(IS_ADC_EXTTRIG(hadc->Init.ExternalTrigConv));
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
assert_param(IS_FUNCTIONAL_STATE(hadc->Init.DMAContinuousRequests));
|
||||
#endif
|
||||
assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
|
||||
assert_param(IS_ADC_OVERRUN(hadc->Init.Overrun));
|
||||
assert_param(IS_FUNCTIONAL_STATE(hadc->Init.LowPowerAutoWait));
|
||||
|
||||
/* As prerequisite, into HAL_ADC_MspInit(), ADC clock must be configured */
|
||||
/* at RCC top level depending on both possible clock sources: */
|
||||
/* APB clock or HSI clock. */
|
||||
/* Refer to header of this file for more details on clock enabling procedure*/
|
||||
|
||||
/* Actions performed only if ADC is coming from state reset: */
|
||||
/* - Initialization of ADC MSP */
|
||||
/* - ADC voltage regulator enable */
|
||||
if (hadc->State == HAL_ADC_STATE_RESET)
|
||||
{
|
||||
/* Initialize ADC error code */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Allocate lock resource and initialize it */
|
||||
hadc->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
/* Init the ADC Callback settings */
|
||||
hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback; /* Legacy weak callback */
|
||||
hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback; /* Legacy weak callback */
|
||||
hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback; /* Legacy weak callback */
|
||||
hadc->ErrorCallback = HAL_ADC_ErrorCallback; /* Legacy weak callback */
|
||||
|
||||
if (hadc->MspInitCallback == NULL)
|
||||
{
|
||||
hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
hadc->MspInitCallback(hadc);
|
||||
#else
|
||||
/* Init the low level hardware */
|
||||
HAL_ADC_MspInit(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Configuration of ADC parameters if previous preliminary actions are */
|
||||
/* correctly completed. */
|
||||
/* and if there is no conversion on going on regular group (ADC can be */
|
||||
/* enabled anyway, in case of call of this function to update a parameter */
|
||||
/* on the fly). */
|
||||
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL) &&
|
||||
(tmp_hal_status == HAL_OK) &&
|
||||
(ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET) )
|
||||
{
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL);
|
||||
|
||||
/* Parameters update conditioned to ADC state: */
|
||||
/* Parameters that can be updated only when ADC is disabled: */
|
||||
/* - ADC clock mode */
|
||||
/* - ADC clock prescaler */
|
||||
/* - ADC resolution */
|
||||
if (ADC_IS_ENABLE(hadc) == RESET)
|
||||
{
|
||||
/* Some parameters of this register are not reset, since they are set */
|
||||
/* by other functions and must be kept in case of usage of this */
|
||||
/* function on the fly (update of a parameter of ADC_InitTypeDef */
|
||||
/* without needing to reconfigure all other ADC groups/channels */
|
||||
/* parameters): */
|
||||
/* - internal measurement paths: temperature sensor, Vref */
|
||||
/* (set into HAL_ADC_ConfigChannel() ) */
|
||||
|
||||
/* Configuration of ADC resolution */
|
||||
MODIFY_REG(hadc->Instance->CFGR1,
|
||||
ADC_CFGR1_RESSEL,
|
||||
hadc->Init.Resolution );
|
||||
|
||||
/* Configuration of ADC clock mode: clock source AHB or HSI with */
|
||||
/* selectable prescaler */
|
||||
MODIFY_REG(hadc->Instance->CFGR2,
|
||||
ADC_CFGR2_CKMODE,
|
||||
hadc->Init.ClockPrescaler );
|
||||
}
|
||||
|
||||
/* Configuration of ADC: */
|
||||
/* - discontinuous mode */
|
||||
/* - LowPowerAutoWait mode */
|
||||
/* - continuous conversion mode */
|
||||
/* - overrun */
|
||||
/* - external trigger to start conversion */
|
||||
/* - external trigger polarity */
|
||||
/* - data alignment */
|
||||
/* - resolution */
|
||||
/* - scan direction */
|
||||
/* - DMA continuous request */
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
hadc->Instance->CFGR1 &= ~( ADC_CFGR1_DISCEN |
|
||||
ADC_CFGR1_CONT |
|
||||
ADC_CFGR1_OVRMOD |
|
||||
ADC_CFGR1_EXTSEL |
|
||||
ADC_CFGR1_EXTEN |
|
||||
ADC_CFGR1_ALIGN |
|
||||
ADC_CFGR1_SCANDIR |
|
||||
ADC_CFGR1_DMACFG );
|
||||
|
||||
tmpCFGR1 |= (ADC_CFGR1_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
|
||||
ADC_CFGR1_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
|
||||
ADC_CFGR1_OVERRUN(hadc->Init.Overrun) |
|
||||
hadc->Init.DataAlign |
|
||||
ADC_SCANDIR(hadc->Init.ScanConvMode) |
|
||||
ADC_CFGR1_DMACONTREQ((uint32_t)hadc->Init.DMAContinuousRequests) );
|
||||
#else
|
||||
hadc->Instance->CFGR1 &= ~( ADC_CFGR1_DISCEN |
|
||||
ADC_CFGR1_CONT |
|
||||
ADC_CFGR1_OVRMOD |
|
||||
ADC_CFGR1_EXTSEL |
|
||||
ADC_CFGR1_EXTEN |
|
||||
ADC_CFGR1_ALIGN |
|
||||
ADC_CFGR1_SCANDIR );
|
||||
|
||||
tmpCFGR1 |= (ADC_CFGR1_AUTOWAIT((uint32_t)hadc->Init.LowPowerAutoWait) |
|
||||
ADC_CFGR1_CONTINUOUS((uint32_t)hadc->Init.ContinuousConvMode) |
|
||||
ADC_CFGR1_OVERRUN(hadc->Init.Overrun) |
|
||||
hadc->Init.DataAlign |
|
||||
ADC_SCANDIR(hadc->Init.ScanConvMode) );
|
||||
#endif
|
||||
|
||||
/* Enable discontinuous mode only if continuous mode is disabled */
|
||||
if (hadc->Init.DiscontinuousConvMode == ENABLE)
|
||||
{
|
||||
if (hadc->Init.ContinuousConvMode == DISABLE)
|
||||
{
|
||||
/* Enable the selected ADC group regular discontinuous mode */
|
||||
tmpCFGR1 |= ADC_CFGR1_DISCEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ADC regular group discontinuous was intended to be enabled, */
|
||||
/* but ADC regular group modes continuous and sequencer discontinuous */
|
||||
/* cannot be enabled simultaneously. */
|
||||
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable external trigger if trigger selection is different of software */
|
||||
/* start. */
|
||||
/* Note: This configuration keeps the hardware feature of parameter */
|
||||
/* ExternalTrigConvEdge "trigger edge none" equivalent to */
|
||||
/* software start. */
|
||||
if (hadc->Init.ExternalTrigConv != ADC_SOFTWARE_START)
|
||||
{
|
||||
tmpCFGR1 |= ( hadc->Init.ExternalTrigConv |
|
||||
hadc->Init.ExternalTrigConvEdge );
|
||||
}
|
||||
|
||||
/* Update ADC configuration register with previous settings */
|
||||
hadc->Instance->CFGR1 |= tmpCFGR1;
|
||||
|
||||
/* Channel sampling time configuration */
|
||||
/* Management of parameters "SamplingTimeCommon" and "SamplingTime" */
|
||||
/* (obsolete): sampling time set in this function if parameter */
|
||||
/* "SamplingTimeCommon" has been set to a valid sampling time. */
|
||||
/* Otherwise, sampling time is set into ADC channel initialization */
|
||||
/* structure with parameter "SamplingTime" (obsolete). */
|
||||
if (IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon))
|
||||
{
|
||||
/* Channel sampling time configuration */
|
||||
/* Clear the old sample time */
|
||||
hadc->Instance->SMPR &= ~(ADC_SMPR_SMP);
|
||||
|
||||
/* Set the new sample time */
|
||||
hadc->Instance->SMPR |= ADC_SMPR_SET(hadc->Init.SamplingTimeCommon);
|
||||
}
|
||||
|
||||
/* Check back that ADC registers have effectively been configured to */
|
||||
/* ensure of no potential problem of ADC core IP clocking. */
|
||||
/* Check through register CFGR1 (excluding analog watchdog configuration: */
|
||||
/* set into separate dedicated function, and bits of ADC resolution set */
|
||||
/* out of temporary variable 'tmpCFGR1'). */
|
||||
if ((hadc->Instance->CFGR1 & ~(ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_RESSEL))
|
||||
== tmpCFGR1)
|
||||
{
|
||||
/* Set ADC error code to none */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Set the ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL,
|
||||
HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
|
||||
tmp_hal_status = HAL_ERROR;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
tmp_hal_status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the ADC peripheral registers to their default reset
|
||||
* values, with deinitialization of the ADC MSP.
|
||||
* @note For devices with several ADCs: reset of ADC common registers is done
|
||||
* only if all ADCs sharing the same common group are disabled.
|
||||
* If this is not the case, reset of these common parameters reset is
|
||||
* bypassed without error reporting: it can be the intended behaviour in
|
||||
* case of reset of a single ADC while the other ADCs sharing the same
|
||||
* common group is still running.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_DeInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check ADC handle */
|
||||
if(hadc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_BUSY_INTERNAL);
|
||||
|
||||
/* Stop potential conversion on going, on regular group */
|
||||
tmp_hal_status = ADC_ConversionStop(hadc);
|
||||
|
||||
/* Disable ADC peripheral if conversions are effectively stopped */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Disable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Disable(hadc);
|
||||
|
||||
/* Check if ADC is effectively disabled */
|
||||
if (tmp_hal_status != HAL_ERROR)
|
||||
{
|
||||
/* Change ADC state */
|
||||
hadc->State = HAL_ADC_STATE_READY;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset ADC peripheral */
|
||||
__HAL_RCC_ADC_FORCE_RESET();
|
||||
__HAL_RCC_ADC_RELEASE_RESET();
|
||||
|
||||
/* Configuration of ADC parameters if previous preliminary actions are */
|
||||
/* correctly completed. */
|
||||
if (tmp_hal_status != HAL_ERROR)
|
||||
{
|
||||
|
||||
/* ========== Reset ADC registers ========== */
|
||||
/* Reset register IER */
|
||||
__HAL_ADC_DISABLE_IT(hadc, (ADC_IT_AWD | ADC_IT_OVR |
|
||||
ADC_IT_EOS | ADC_IT_EOC |
|
||||
ADC_IT_EOSMP /*| ADC_IT_RDY*/ ) );
|
||||
|
||||
/* Reset register ISR */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_OVR |
|
||||
ADC_FLAG_EOS | ADC_FLAG_EOC |
|
||||
ADC_FLAG_EOSMP /*| ADC_FLAG_RDY*/ ) );
|
||||
|
||||
/* Reset register CR */
|
||||
/* Bits ADC_CR_ADCAL, ADC_CR_ADSTP, ADC_CR_ADSTART are in access mode */
|
||||
/* "read-set": no direct reset applicable. */
|
||||
|
||||
/* Reset register CFGR1 */
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
hadc->Instance->CFGR1 &= ~(ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN |
|
||||
/*ADC_CFGR1_AUTOFF |*/ ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD |
|
||||
ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RESSEL |
|
||||
ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN );
|
||||
#else
|
||||
hadc->Instance->CFGR1 &= ~(ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN |
|
||||
/*ADC_CFGR1_AUTOFF |*/ ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD |
|
||||
ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RESSEL |
|
||||
ADC_CFGR1_SCANDIR );
|
||||
#endif
|
||||
|
||||
/* Reset register CFGR2 */
|
||||
/* Note: Update of ADC clock mode is conditioned to ADC state disabled: */
|
||||
/* already done above. */
|
||||
hadc->Instance->CFGR2 &= ~ADC_CFGR2_CKMODE;
|
||||
|
||||
/* Reset register SMPR */
|
||||
hadc->Instance->SMPR &= ~ADC_SMPR_SMP;
|
||||
|
||||
/* Reset register TR */
|
||||
hadc->Instance->TR &= ~(ADC_TR_HT | ADC_TR_LT);
|
||||
|
||||
/* Reset register CHSELR */
|
||||
hadc->Instance->CHSELR &= ~(ADC_CHSELR_CHSEL12 | ADC_CHSELR_CHSEL11 | ADC_CHSELR_CHSEL9 | ADC_CHSELR_CHSEL8 |
|
||||
ADC_CHSELR_CHSEL7 | ADC_CHSELR_CHSEL6 | ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL4 |
|
||||
ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL0 );
|
||||
|
||||
/* Reset register DR */
|
||||
/* bits in access mode read only, no direct reset applicable*/
|
||||
|
||||
/* Reset register CCR */
|
||||
ADC->CCR &= ~(ADC_CCR_ALL);
|
||||
|
||||
/* ========== Hard reset ADC peripheral ========== */
|
||||
/* Performs a global reset of the entire ADC peripheral: ADC state is */
|
||||
/* forced to a similar state after device power-on. */
|
||||
/* If needed, copy-paste and uncomment the following reset code into */
|
||||
/* function "void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)": */
|
||||
/* */
|
||||
/* __HAL_RCC_ADC1_FORCE_RESET() */
|
||||
/* __HAL_RCC_ADC1_RELEASE_RESET() */
|
||||
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
if (hadc->MspDeInitCallback == NULL)
|
||||
{
|
||||
hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
|
||||
}
|
||||
|
||||
/* DeInit the low level hardware */
|
||||
hadc->MspDeInitCallback(hadc);
|
||||
#else
|
||||
/* DeInit the low level hardware */
|
||||
HAL_ADC_MspDeInit(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
|
||||
/* Set ADC error code to none */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Set ADC state */
|
||||
hadc->State = HAL_ADC_STATE_RESET;
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initializes the ADC MSP.
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_MspInit must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the ADC MSP.
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_MspDeInit must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User ADC Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param hadc Pointer to a ADC_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified ADC.
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID
|
||||
* @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID
|
||||
* @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID
|
||||
* @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID
|
||||
* @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID
|
||||
* @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_RegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID, pADC_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if ((hadc->State & HAL_ADC_STATE_READY) != 0)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
|
||||
hadc->ConvCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_CONVERSION_HALF_CB_ID :
|
||||
hadc->ConvHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
|
||||
hadc->LevelOutOfWindowCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_ERROR_CB_ID :
|
||||
hadc->ErrorCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPINIT_CB_ID :
|
||||
hadc->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPDEINIT_CB_ID :
|
||||
hadc->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_ADC_STATE_RESET == hadc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_ADC_MSPINIT_CB_ID :
|
||||
hadc->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPDEINIT_CB_ID :
|
||||
hadc->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a ADC Callback
|
||||
* ADC callback is redirected to the weak predefined callback
|
||||
* @param hadc Pointer to a ADC_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified ADC.
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_ADC_CONVERSION_COMPLETE_CB_ID ADC conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_CONVERSION_HALF_CB_ID ADC conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID ADC analog watchdog 1 callback ID
|
||||
* @arg @ref HAL_ADC_ERROR_CB_ID ADC error callback ID
|
||||
* @arg @ref HAL_ADC_INJ_CONVERSION_COMPLETE_CB_ID ADC group injected conversion complete callback ID
|
||||
* @arg @ref HAL_ADC_MSPINIT_CB_ID ADC Msp Init callback ID
|
||||
* @arg @ref HAL_ADC_MSPDEINIT_CB_ID ADC Msp DeInit callback ID
|
||||
* @arg @ref HAL_ADC_MSPINIT_CB_ID MspInit callback ID
|
||||
* @arg @ref HAL_ADC_MSPDEINIT_CB_ID MspDeInit callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_UnRegisterCallback(ADC_HandleTypeDef *hadc, HAL_ADC_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if ((hadc->State & HAL_ADC_STATE_READY) != 0)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_ADC_CONVERSION_COMPLETE_CB_ID :
|
||||
hadc->ConvCpltCallback = HAL_ADC_ConvCpltCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_CONVERSION_HALF_CB_ID :
|
||||
hadc->ConvHalfCpltCallback = HAL_ADC_ConvHalfCpltCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_LEVEL_OUT_OF_WINDOW_1_CB_ID :
|
||||
hadc->LevelOutOfWindowCallback = HAL_ADC_LevelOutOfWindowCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_ERROR_CB_ID :
|
||||
hadc->ErrorCallback = HAL_ADC_ErrorCallback;
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPINIT_CB_ID :
|
||||
hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPDEINIT_CB_ID :
|
||||
hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_ADC_STATE_RESET == hadc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_ADC_MSPINIT_CB_ID :
|
||||
hadc->MspInitCallback = HAL_ADC_MspInit; /* Legacy weak MspInit */
|
||||
break;
|
||||
|
||||
case HAL_ADC_MSPDEINIT_CB_ID :
|
||||
hadc->MspDeInitCallback = HAL_ADC_MspDeInit; /* Legacy weak MspDeInit */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hadc->ErrorCode |= HAL_ADC_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Exported_Functions_Group2 IO operation functions
|
||||
* @brief IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Start conversion of regular group.
|
||||
(+) Stop conversion of regular group.
|
||||
(+) Poll for conversion complete on regular group.
|
||||
(+) Poll for conversion event.
|
||||
(+) Get result of regular channel conversion.
|
||||
(+) Start conversion of regular group and enable interruptions.
|
||||
(+) Stop conversion of regular group and disable interruptions.
|
||||
(+) Handle ADC interrupt request
|
||||
(+) Start conversion of regular group and enable DMA transfer.
|
||||
(+) Stop conversion of regular group and disable ADC DMA transfer.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enables ADC, starts conversion of regular group.
|
||||
* Interruptions enabled in this function: None.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Perform ADC enable and conversion start if no conversion is on going */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Enable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Enable(hadc);
|
||||
|
||||
/* Start conversion if ADC is effectively enabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
/* - Clear state bitfield related to regular group conversion results */
|
||||
/* - Set state bitfield related to regular operation */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
|
||||
HAL_ADC_STATE_REG_BUSY);
|
||||
|
||||
/* Reset ADC all error code fields */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Process unlocked */
|
||||
/* Unlock before starting ADC conversions: in case of potential */
|
||||
/* interruption, to let the process to ADC IRQ Handler. */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Clear regular group conversion flag and overrun flag */
|
||||
/* (To ensure of no unknown state from potential previous ADC */
|
||||
/* operations) */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
|
||||
|
||||
/* Enable conversion of regular group. */
|
||||
/* If software start has been selected, conversion starts immediately. */
|
||||
/* If external trigger has been selected, conversion will start at next */
|
||||
/* trigger event. */
|
||||
hadc->Instance->CR |= ADC_CR_ADSTART;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_hal_status = HAL_BUSY;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop ADC conversion of regular group, disable ADC peripheral.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* 1. Stop potential conversion on going, on regular group */
|
||||
tmp_hal_status = ADC_ConversionStop(hadc);
|
||||
|
||||
/* Disable ADC peripheral if conversions are effectively stopped */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* 2. Disable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Disable(hadc);
|
||||
|
||||
/* Check if ADC is effectively disabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for regular group conversion to be completed.
|
||||
* @note ADC conversion flags EOS (end of sequence) and EOC (end of
|
||||
* conversion) are cleared by this function, with an exception:
|
||||
* if low power feature "LowPowerAutoWait" is enabled, flags are
|
||||
* not cleared to not interfere with this feature until data register
|
||||
* is read using function HAL_ADC_GetValue().
|
||||
* @note This function cannot be used in a particular setup: ADC configured
|
||||
* in DMA mode and polling for end of each conversion (ADC init
|
||||
* parameter "EOCSelection" set to ADC_EOC_SINGLE_CONV).
|
||||
* In this case, DMA resets the flag EOC and polling cannot be
|
||||
* performed on each conversion. Nevertheless, polling can still
|
||||
* be performed on the complete sequence (ADC init
|
||||
* parameter "EOCSelection" set to ADC_EOC_SEQ_CONV).
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param hadc ADC handle
|
||||
* @param Timeout Timeout value in millisecond.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
uint32_t tmp_Flag_EOC;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* If end of conversion selected to end of sequence */
|
||||
if (hadc->Init.EOCSelection == ADC_EOC_SEQ_CONV)
|
||||
{
|
||||
tmp_Flag_EOC = ADC_FLAG_EOS;
|
||||
}
|
||||
/* If end of conversion selected to end of each conversion */
|
||||
else /* ADC_EOC_SINGLE_CONV */
|
||||
{
|
||||
/* Verification that ADC configuration is compliant with polling for */
|
||||
/* each conversion: */
|
||||
/* Particular case is ADC configured in DMA mode and ADC sequencer with */
|
||||
/* several ranks and polling for end of each conversion. */
|
||||
/* For code simplicity sake, this particular case is generalized to */
|
||||
/* ADC configured in DMA mode and and polling for end of each conversion. */
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
if (HAL_IS_BIT_SET(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN))
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
tmp_Flag_EOC = (ADC_FLAG_EOC | ADC_FLAG_EOS);
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Get tick count */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait until End of Conversion flag is raised */
|
||||
while(HAL_IS_BIT_CLR(hadc->Instance->ISR, tmp_Flag_EOC))
|
||||
{
|
||||
/* Check if timeout is disabled (set to infinite wait) */
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
|
||||
{
|
||||
/* Update ADC state machine to timeout */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update ADC state machine */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
|
||||
|
||||
/* Determine whether any further conversion upcoming on group regular */
|
||||
/* by external trigger, continuous mode or scan sequence on going. */
|
||||
if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
|
||||
(hadc->Init.ContinuousConvMode == DISABLE) )
|
||||
{
|
||||
/* If End of Sequence is reached, disable interrupts */
|
||||
if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) )
|
||||
{
|
||||
/* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */
|
||||
/* ADSTART==0 (no conversion on going) */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Disable ADC end of single conversion interrupt on group regular */
|
||||
/* Note: Overrun interrupt was enabled with EOC interrupt in */
|
||||
/* HAL_Start_IT(), but is not disabled here because can be used */
|
||||
/* by overrun IRQ process below. */
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
|
||||
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change ADC state to error state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear end of conversion flag of regular group if low power feature */
|
||||
/* "LowPowerAutoWait " is disabled, to not interfere with this feature */
|
||||
/* until data register is read using function HAL_ADC_GetValue(). */
|
||||
if (hadc->Init.LowPowerAutoWait == DISABLE)
|
||||
{
|
||||
/* Clear regular group conversion flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS));
|
||||
}
|
||||
|
||||
/* Return ADC state */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Poll for conversion event.
|
||||
* @param hadc ADC handle
|
||||
* @param EventType the ADC event type.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg ADC_AWD_EVENT: ADC Analog watchdog event
|
||||
* @arg ADC_OVR_EVENT: ADC Overrun event
|
||||
* @param Timeout Timeout value in millisecond.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout)
|
||||
{
|
||||
uint32_t tickstart=0;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
assert_param(IS_ADC_EVENT_TYPE(EventType));
|
||||
|
||||
/* Get tick count */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Check selected event flag */
|
||||
while(__HAL_ADC_GET_FLAG(hadc, EventType) == RESET)
|
||||
{
|
||||
/* Check if timeout is disabled (set to infinite wait) */
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout))
|
||||
{
|
||||
/* Update ADC state machine to timeout */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_TIMEOUT);
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(EventType)
|
||||
{
|
||||
/* Analog watchdog (level out of window) event */
|
||||
case ADC_AWD_EVENT:
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
|
||||
|
||||
/* Clear ADC analog watchdog flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
|
||||
break;
|
||||
|
||||
/* Overrun event */
|
||||
default: /* Case ADC_OVR_EVENT */
|
||||
/* If overrun is set to overwrite previous data, overrun event is not */
|
||||
/* considered as an error. */
|
||||
/* (cf ref manual "Managing conversions without using the DMA and without */
|
||||
/* overrun ") */
|
||||
if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
|
||||
{
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_REG_OVR);
|
||||
|
||||
/* Set ADC error code to overrun */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
|
||||
}
|
||||
|
||||
/* Clear ADC Overrun flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return ADC state */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables ADC, starts conversion of regular group with interruption.
|
||||
* Interruptions enabled in this function:
|
||||
* - EOC (end of conversion of regular group) or EOS (end of
|
||||
* sequence of regular group) depending on ADC initialization
|
||||
* parameter "EOCSelection"
|
||||
* - overrun (if available)
|
||||
* Each of these interruptions has its dedicated callback function.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Perform ADC enable and conversion start if no conversion is on going */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Enable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Enable(hadc);
|
||||
|
||||
/* Start conversion if ADC is effectively enabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
/* - Clear state bitfield related to regular group conversion results */
|
||||
/* - Set state bitfield related to regular operation */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
|
||||
HAL_ADC_STATE_REG_BUSY);
|
||||
|
||||
/* Reset ADC all error code fields */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Process unlocked */
|
||||
/* Unlock before starting ADC conversions: in case of potential */
|
||||
/* interruption, to let the process to ADC IRQ Handler. */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Clear regular group conversion flag and overrun flag */
|
||||
/* (To ensure of no unknown state from potential previous ADC */
|
||||
/* operations) */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
|
||||
|
||||
/* Enable ADC end of conversion interrupt */
|
||||
/* Enable ADC overrun interrupt */
|
||||
switch(hadc->Init.EOCSelection)
|
||||
{
|
||||
case ADC_EOC_SEQ_CONV:
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC);
|
||||
__HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOS | ADC_IT_OVR));
|
||||
break;
|
||||
/* case ADC_EOC_SINGLE_CONV */
|
||||
default:
|
||||
__HAL_ADC_ENABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable conversion of regular group. */
|
||||
/* If software start has been selected, conversion starts immediately. */
|
||||
/* If external trigger has been selected, conversion will start at next */
|
||||
/* trigger event. */
|
||||
hadc->Instance->CR |= ADC_CR_ADSTART;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_hal_status = HAL_BUSY;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Stop ADC conversion of regular group, disable interruption of
|
||||
* end-of-conversion, disable ADC peripheral.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* 1. Stop potential conversion on going, on regular group */
|
||||
tmp_hal_status = ADC_ConversionStop(hadc);
|
||||
|
||||
/* Disable ADC peripheral if conversions are effectively stopped */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Disable ADC end of conversion interrupt for regular group */
|
||||
/* Disable ADC overrun interrupt */
|
||||
__HAL_ADC_DISABLE_IT(hadc, (ADC_IT_EOC | ADC_IT_EOS | ADC_IT_OVR));
|
||||
|
||||
/* 2. Disable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Disable(hadc);
|
||||
|
||||
/* Check if ADC is effectively disabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief Enables ADC, starts conversion of regular group and transfers result
|
||||
* through DMA.
|
||||
* Interruptions enabled in this function:
|
||||
* - DMA transfer complete
|
||||
* - DMA half transfer
|
||||
* - overrun
|
||||
* Each of these interruptions has its dedicated callback function.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param hadc ADC handle
|
||||
* @param pData The destination Buffer address.
|
||||
* @param Length The length of data to be transferred from ADC peripheral to memory.
|
||||
* @retval HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Perform ADC enable and conversion start if no conversion is on going */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Enable the ADC peripheral */
|
||||
tmp_hal_status = ADC_Enable(hadc);
|
||||
|
||||
/* Start conversion if ADC is effectively enabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
/* - Clear state bitfield related to regular group conversion results */
|
||||
/* - Set state bitfield related to regular operation */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_READY | HAL_ADC_STATE_REG_EOC | HAL_ADC_STATE_REG_OVR | HAL_ADC_STATE_REG_EOSMP,
|
||||
HAL_ADC_STATE_REG_BUSY);
|
||||
|
||||
/* Reset ADC all error code fields */
|
||||
ADC_CLEAR_ERRORCODE(hadc);
|
||||
|
||||
/* Process unlocked */
|
||||
/* Unlock before starting ADC conversions: in case of potential */
|
||||
/* interruption, to let the process to ADC IRQ Handler. */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Set the DMA transfer complete callback */
|
||||
hadc->DMA_Handle->XferCpltCallback = ADC_DMAConvCplt;
|
||||
|
||||
/* Set the DMA half transfer complete callback */
|
||||
hadc->DMA_Handle->XferHalfCpltCallback = ADC_DMAHalfConvCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
hadc->DMA_Handle->XferErrorCallback = ADC_DMAError;
|
||||
|
||||
|
||||
/* Manage ADC and DMA start: ADC overrun interruption, DMA start, ADC */
|
||||
/* start (in case of SW start): */
|
||||
|
||||
/* Clear regular group conversion flag and overrun flag */
|
||||
/* (To ensure of no unknown state from potential previous ADC */
|
||||
/* operations) */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS | ADC_FLAG_OVR));
|
||||
|
||||
/* Enable ADC overrun interrupt */
|
||||
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_OVR);
|
||||
|
||||
/* Enable ADC DMA mode */
|
||||
hadc->Instance->CFGR1 |= ADC_CFGR1_DMAEN;
|
||||
|
||||
/* Start the DMA channel */
|
||||
HAL_DMA_Start_IT(hadc->DMA_Handle, (uint32_t)&hadc->Instance->DR, (uint32_t)pData, Length);
|
||||
|
||||
/* Enable conversion of regular group. */
|
||||
/* If software start has been selected, conversion starts immediately. */
|
||||
/* If external trigger has been selected, conversion will start at next */
|
||||
/* trigger event. */
|
||||
hadc->Instance->CR |= ADC_CR_ADSTART;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp_hal_status = HAL_BUSY;
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop ADC conversion of regular group, disable ADC DMA transfer, disable
|
||||
* ADC peripheral.
|
||||
* Each of these interruptions has its dedicated callback function.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* 1. Stop potential conversion on going, on regular group */
|
||||
tmp_hal_status = ADC_ConversionStop(hadc);
|
||||
|
||||
/* Disable ADC peripheral if conversions are effectively stopped */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Disable ADC DMA (ADC DMA configuration ADC_CFGR_DMACFG is kept) */
|
||||
hadc->Instance->CFGR1 &= ~ADC_CFGR1_DMAEN;
|
||||
|
||||
/* Disable the DMA channel (in case of DMA in circular mode or stop while */
|
||||
/* while DMA transfer is on going) */
|
||||
tmp_hal_status = HAL_DMA_Abort(hadc->DMA_Handle);
|
||||
|
||||
/* Check if DMA channel effectively disabled */
|
||||
if (tmp_hal_status != HAL_OK)
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
|
||||
}
|
||||
|
||||
/* Disable ADC overrun interrupt */
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_OVR);
|
||||
|
||||
/* 2. Disable the ADC peripheral */
|
||||
/* Update "tmp_hal_status" only if DMA channel disabling passed, to keep */
|
||||
/* in memory a potential failing status. */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
tmp_hal_status = ADC_Disable(hadc);
|
||||
}
|
||||
else
|
||||
{
|
||||
ADC_Disable(hadc);
|
||||
}
|
||||
|
||||
/* Check if ADC is effectively disabled */
|
||||
if (tmp_hal_status == HAL_OK)
|
||||
{
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Get ADC regular group conversion result.
|
||||
* @note Reading register DR automatically clears ADC flag EOC
|
||||
* (ADC group regular end of unitary conversion).
|
||||
* @note This function does not clear ADC flag EOS
|
||||
* (ADC group regular end of sequence conversion).
|
||||
* Occurrence of flag EOS rising:
|
||||
* - If sequencer is composed of 1 rank, flag EOS is equivalent
|
||||
* to flag EOC.
|
||||
* - If sequencer is composed of several ranks, during the scan
|
||||
* sequence flag EOC only is raised, at the end of the scan sequence
|
||||
* both flags EOC and EOS are raised.
|
||||
* To clear this flag, either use function:
|
||||
* in programming model IT: @ref HAL_ADC_IRQHandler(), in programming
|
||||
* model polling: @ref HAL_ADC_PollForConversion()
|
||||
* or @ref __HAL_ADC_CLEAR_FLAG(&hadc, ADC_FLAG_EOS).
|
||||
* @param hadc ADC handle
|
||||
* @retval ADC group regular conversion data
|
||||
*/
|
||||
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Note: EOC flag is not cleared here by software because automatically */
|
||||
/* cleared by hardware when reading register DR. */
|
||||
|
||||
/* Return ADC converted value */
|
||||
return hadc->Instance->DR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles ADC interrupt request.
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
|
||||
assert_param(IS_ADC_EOC_SELECTION(hadc->Init.EOCSelection));
|
||||
|
||||
/* ========== Check End of Conversion flag for regular group ========== */
|
||||
if( (__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOC)) ||
|
||||
(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_EOS)) )
|
||||
{
|
||||
/* Update state machine on conversion status if not in error state */
|
||||
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL))
|
||||
{
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
|
||||
}
|
||||
|
||||
/* Determine whether any further conversion upcoming on group regular */
|
||||
/* by external trigger, continuous mode or scan sequence on going. */
|
||||
if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
|
||||
(hadc->Init.ContinuousConvMode == DISABLE) )
|
||||
{
|
||||
/* If End of Sequence is reached, disable interrupts */
|
||||
if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) )
|
||||
{
|
||||
/* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */
|
||||
/* ADSTART==0 (no conversion on going) */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Disable ADC end of single conversion interrupt on group regular */
|
||||
/* Note: Overrun interrupt was enabled with EOC interrupt in */
|
||||
/* HAL_Start_IT(), but is not disabled here because can be used */
|
||||
/* by overrun IRQ process below. */
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
|
||||
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change ADC state to error state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: into callback, to determine if conversion has been triggered */
|
||||
/* from EOC or EOS, possibility to use: */
|
||||
/* " if( __HAL_ADC_GET_FLAG(&hadc, ADC_FLAG_EOS)) " */
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->ConvCpltCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_ConvCpltCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
|
||||
|
||||
/* Clear regular group conversion flag */
|
||||
/* Note: in case of overrun set to ADC_OVR_DATA_PRESERVED, end of */
|
||||
/* conversion flags clear induces the release of the preserved data.*/
|
||||
/* Therefore, if the preserved data value is needed, it must be */
|
||||
/* read preliminarily into HAL_ADC_ConvCpltCallback(). */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_EOC | ADC_FLAG_EOS) );
|
||||
}
|
||||
|
||||
/* ========== Check Analog watchdog flags ========== */
|
||||
if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_AWD) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_AWD))
|
||||
{
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_AWD1);
|
||||
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->LevelOutOfWindowCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_LevelOutOfWindowCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
|
||||
/* Clear ADC Analog watchdog flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_AWD);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ========== Check Overrun flag ========== */
|
||||
if(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_OVR) && __HAL_ADC_GET_IT_SOURCE(hadc, ADC_IT_OVR))
|
||||
{
|
||||
/* If overrun is set to overwrite previous data (default setting), */
|
||||
/* overrun event is not considered as an error. */
|
||||
/* (cf ref manual "Managing conversions without using the DMA and without */
|
||||
/* overrun ") */
|
||||
/* Exception for usage with DMA overrun event always considered as an */
|
||||
/* error. */
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
if ((hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED) ||
|
||||
HAL_IS_BIT_SET(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN) )
|
||||
#else
|
||||
if (hadc->Init.Overrun == ADC_OVR_DATA_PRESERVED)
|
||||
#endif
|
||||
{
|
||||
/* Set ADC error code to overrun */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_OVR);
|
||||
|
||||
/* Clear ADC overrun flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
|
||||
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->ErrorCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_ErrorCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Clear the Overrun flag */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_FLAG_OVR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conversion complete callback in non blocking mode
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_ConvCpltCallback must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Conversion DMA half-transfer callback in non blocking mode
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_ConvHalfCpltCallback must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Analog watchdog callback in non blocking mode.
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_LevelOoutOfWindowCallback must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ADC error callback in non blocking mode
|
||||
* (ADC conversion with interruption or transfer by DMA)
|
||||
* @param hadc ADC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hadc);
|
||||
|
||||
/* NOTE : This function should not be modified. When the callback is needed,
|
||||
function HAL_ADC_ErrorCallback must be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Exported_Functions_Group3 Peripheral Control functions
|
||||
* @brief Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure channels on regular group
|
||||
(+) Configure the analog watchdog
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures the the selected channel to be linked to the regular
|
||||
* group.
|
||||
* @note In case of usage of internal measurement channels:
|
||||
* VrefInt/TempSensor.
|
||||
* Sampling time constraints must be respected (sampling time can be
|
||||
* adjusted in function of ADC clock frequency and sampling time
|
||||
* setting).
|
||||
* Refer to device datasheet for timings values, parameters TS_vrefint,
|
||||
* TS_temp (values rough order: 5us to 17us).
|
||||
* These internal paths can be be disabled using function
|
||||
* HAL_ADC_DeInit().
|
||||
* @note Possibility to update parameters on the fly:
|
||||
* This function initializes channel into regular group, following
|
||||
* calls to this function can be used to reconfigure some parameters
|
||||
* of structure "ADC_ChannelConfTypeDef" on the fly, without reseting
|
||||
* the ADC.
|
||||
* The setting of these parameters is conditioned to ADC state.
|
||||
* For parameters constraints, see comments of structure
|
||||
* "ADC_ChannelConfTypeDef".
|
||||
* @param hadc ADC handle
|
||||
* @param sConfig Structure of ADC channel for regular group.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_ConfigChannel(ADC_HandleTypeDef* hadc, ADC_ChannelConfTypeDef* sConfig)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
__IO uint32_t wait_loop_index = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
assert_param(IS_ADC_CHANNEL(sConfig->Channel));
|
||||
assert_param(IS_ADC_RANK(sConfig->Rank));
|
||||
|
||||
if (! IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon))
|
||||
{
|
||||
assert_param(IS_ADC_SAMPLE_TIME(sConfig->SamplingTime));
|
||||
}
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Parameters update conditioned to ADC state: */
|
||||
/* Parameters that can be updated when ADC is disabled or enabled without */
|
||||
/* conversion on going on regular group: */
|
||||
/* - Channel number */
|
||||
/* - Channel sampling time */
|
||||
/* - Management of internal measurement channels: VrefInt/TempSensor */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Configure channel: depending on rank setting, add it or remove it from */
|
||||
/* ADC conversion sequencer. */
|
||||
if (sConfig->Rank != ADC_RANK_NONE)
|
||||
{
|
||||
/* Regular sequence configuration */
|
||||
/* Set the channel selection register from the selected channel */
|
||||
hadc->Instance->CHSELR |= ADC_CHSELR_CHANNEL(sConfig->Channel);
|
||||
|
||||
/* Channel sampling time configuration */
|
||||
/* Management of parameters "SamplingTimeCommon" and "SamplingTime" */
|
||||
/* (obsolete): sampling time set in this function with */
|
||||
/* parameter "SamplingTime" (obsolete) only if not already set into */
|
||||
/* ADC initialization structure with parameter "SamplingTimeCommon". */
|
||||
if (! IS_ADC_SAMPLE_TIME(hadc->Init.SamplingTimeCommon))
|
||||
{
|
||||
/* Modify sampling time if needed (not needed in case of reoccurrence */
|
||||
/* for several channels programmed consecutively into the sequencer) */
|
||||
if (sConfig->SamplingTime != ADC_GET_SAMPLINGTIME(hadc))
|
||||
{
|
||||
/* Channel sampling time configuration */
|
||||
/* Clear the old sample time */
|
||||
hadc->Instance->SMPR &= ~(ADC_SMPR_SMP);
|
||||
|
||||
/* Set the new sample time */
|
||||
hadc->Instance->SMPR |= ADC_SMPR_SET(sConfig->SamplingTime);
|
||||
}
|
||||
}
|
||||
|
||||
/* Management of internal measurement channels: VrefInt/TempSensor */
|
||||
/* internal measurement paths enable: If internal channel selected, */
|
||||
/* enable dedicated internal buffers and path. */
|
||||
/* Note: these internal measurement paths can be disabled using */
|
||||
/* HAL_ADC_DeInit() or removing the channel from sequencer with */
|
||||
/* channel configuration parameter "Rank". */
|
||||
if(ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
|
||||
{
|
||||
/* If Channel_11 is selected, enable Temp. sensor measurement path. */
|
||||
/* If Channel_12 is selected, enable VREFINT measurement path. */
|
||||
|
||||
ADC->CCR |= ADC_CHANNEL_INTERNAL_PATH(sConfig->Channel);
|
||||
|
||||
/* If Temp. sensor is selected, wait for stabilization delay */
|
||||
if (sConfig->Channel == ADC_CHANNEL_TEMPSENSOR)
|
||||
{
|
||||
/* Delay for temperature sensor stabilization time */
|
||||
/* Compute number of CPU cycles to wait for */
|
||||
wait_loop_index = (ADC_TEMPSENSOR_DELAY_US * (SystemCoreClock / 1000000U));
|
||||
while(wait_loop_index != 0U)
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Regular sequence configuration */
|
||||
/* Reset the channel selection register from the selected channel */
|
||||
hadc->Instance->CHSELR &= ~ADC_CHSELR_CHANNEL(sConfig->Channel);
|
||||
|
||||
/* Management of internal measurement channels: VrefInt/TempSensor */
|
||||
/* internal measurement paths disable: If internal channel selected, */
|
||||
/* disable dedicated internal buffers and path. */
|
||||
if(ADC_IS_CHANNEL_INTERNAL(sConfig->Channel))
|
||||
{
|
||||
ADC->CCR &= ~ADC_CHANNEL_INTERNAL_PATH(sConfig->Channel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* If a conversion is on going on regular group, no update on regular */
|
||||
/* channel could be done on neither of the channel configuration structure */
|
||||
/* parameters. */
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
tmp_hal_status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configures the analog watchdog.
|
||||
* @note Possibility to update parameters on the fly:
|
||||
* This function initializes the selected analog watchdog, following
|
||||
* calls to this function can be used to reconfigure some parameters
|
||||
* of structure "ADC_AnalogWDGConfTypeDef" on the fly, without reseting
|
||||
* the ADC.
|
||||
* The setting of these parameters is conditioned to ADC state.
|
||||
* For parameters constraints, see comments of structure
|
||||
* "ADC_AnalogWDGConfTypeDef".
|
||||
* @param hadc ADC handle
|
||||
* @param AnalogWDGConfig Structure of ADC analog watchdog configuration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_AnalogWDGConfig(ADC_HandleTypeDef* hadc, ADC_AnalogWDGConfTypeDef* AnalogWDGConfig)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
|
||||
uint32_t tmpAWDHighThresholdShifted;
|
||||
uint32_t tmpAWDLowThresholdShifted;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
assert_param(IS_ADC_ANALOG_WATCHDOG_MODE(AnalogWDGConfig->WatchdogMode));
|
||||
assert_param(IS_FUNCTIONAL_STATE(AnalogWDGConfig->ITMode));
|
||||
|
||||
/* Verify if threshold is within the selected ADC resolution */
|
||||
assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->HighThreshold));
|
||||
assert_param(IS_ADC_RANGE(ADC_GET_RESOLUTION(hadc), AnalogWDGConfig->LowThreshold));
|
||||
|
||||
if(AnalogWDGConfig->WatchdogMode == ADC_ANALOGWATCHDOG_SINGLE_REG)
|
||||
{
|
||||
assert_param(IS_ADC_CHANNEL(AnalogWDGConfig->Channel));
|
||||
}
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Parameters update conditioned to ADC state: */
|
||||
/* Parameters that can be updated when ADC is disabled or enabled without */
|
||||
/* conversion on going on regular group: */
|
||||
/* - Analog watchdog channels */
|
||||
/* - Analog watchdog thresholds */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Configuration of analog watchdog: */
|
||||
/* - Set the analog watchdog enable mode: one or overall group of */
|
||||
/* channels. */
|
||||
/* - Set the Analog watchdog channel (is not used if watchdog */
|
||||
/* mode "all channels": ADC_CFGR_AWD1SGL=0). */
|
||||
hadc->Instance->CFGR1 &= ~( ADC_CFGR1_AWDSGL |
|
||||
ADC_CFGR1_AWDEN |
|
||||
ADC_CFGR1_AWDCH );
|
||||
|
||||
hadc->Instance->CFGR1 |= ( AnalogWDGConfig->WatchdogMode |
|
||||
ADC_CFGR_AWDCH(AnalogWDGConfig->Channel) );
|
||||
|
||||
/* Shift the offset in function of the selected ADC resolution: Thresholds*/
|
||||
/* have to be left-aligned on bit 11, the LSB (right bits) are set to 0 */
|
||||
tmpAWDHighThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->HighThreshold);
|
||||
tmpAWDLowThresholdShifted = ADC_AWD1THRESHOLD_SHIFT_RESOLUTION(hadc, AnalogWDGConfig->LowThreshold);
|
||||
|
||||
/* Set the high and low thresholds */
|
||||
hadc->Instance->TR &= ~(ADC_TR_HT | ADC_TR_LT);
|
||||
hadc->Instance->TR |= ( ADC_TRX_HIGHTHRESHOLD (tmpAWDHighThresholdShifted) |
|
||||
tmpAWDLowThresholdShifted );
|
||||
|
||||
/* Clear the ADC Analog watchdog flag (in case of left enabled by */
|
||||
/* previous ADC operations) to be ready to use for HAL_ADC_IRQHandler() */
|
||||
/* or HAL_ADC_PollForEvent(). */
|
||||
__HAL_ADC_CLEAR_FLAG(hadc, ADC_IT_AWD);
|
||||
|
||||
/* Configure ADC Analog watchdog interrupt */
|
||||
if(AnalogWDGConfig->ITMode == ENABLE)
|
||||
{
|
||||
/* Enable the ADC Analog watchdog interrupt */
|
||||
__HAL_ADC_ENABLE_IT(hadc, ADC_IT_AWD);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the ADC Analog watchdog interrupt */
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_AWD);
|
||||
}
|
||||
|
||||
}
|
||||
/* If a conversion is on going on regular group, no update could be done */
|
||||
/* on neither of the AWD configuration structure parameters. */
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
tmp_hal_status = HAL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup ADC_Exported_Functions_Group4 Peripheral State functions
|
||||
* @brief Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State and Errors functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions to get in run-time the status of the
|
||||
peripheral.
|
||||
(+) Check the ADC state
|
||||
(+) Check the ADC error code
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the ADC state
|
||||
* @note ADC state machine is managed by bitfields, ADC status must be
|
||||
* compared with states bits.
|
||||
* For example:
|
||||
* " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_REG_BUSY)) "
|
||||
* " if (HAL_IS_BIT_SET(HAL_ADC_GetState(hadc1), HAL_ADC_STATE_AWD1) ) "
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
uint32_t HAL_ADC_GetState(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Return ADC state */
|
||||
return hadc->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the ADC error code
|
||||
* @param hadc ADC handle
|
||||
* @retval ADC Error Code
|
||||
*/
|
||||
uint32_t HAL_ADC_GetError(ADC_HandleTypeDef *hadc)
|
||||
{
|
||||
return hadc->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup ADC_Private_Functions ADC Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable the selected ADC.
|
||||
* @note Prerequisite condition to use this function: ADC must be disabled
|
||||
* and voltage regulator must be enabled (done into HAL_ADC_Init()).
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
static HAL_StatusTypeDef ADC_Enable(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
__IO uint32_t wait_loop_index = 0U;
|
||||
|
||||
/* ADC enable and wait for ADC ready (in case of ADC is disabled or */
|
||||
/* enabling phase not yet completed: flag ADC ready not yet set). */
|
||||
/* Timeout implemented to not be stuck if ADC cannot be enabled (possible */
|
||||
/* causes: ADC clock not running, ...). */
|
||||
if (ADC_IS_ENABLE(hadc) == RESET)
|
||||
{
|
||||
/* Check if conditions to enable the ADC are fulfilled */
|
||||
if (ADC_ENABLING_CONDITIONS(hadc) == RESET)
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Enable the ADC peripheral */
|
||||
__HAL_ADC_ENABLE(hadc);
|
||||
|
||||
/* Delay for ADC stabilization time */
|
||||
/* Compute number of CPU cycles to wait for */
|
||||
wait_loop_index = (ADC_STAB_DELAY_US * (SystemCoreClock / 1000000U));
|
||||
while(wait_loop_index != 0U)
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return HAL status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the selected ADC.
|
||||
* @note Prerequisite condition to use this function: ADC conversions must be
|
||||
* stopped.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
static HAL_StatusTypeDef ADC_Disable(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Verification if ADC is not already disabled: */
|
||||
/* Note: forbidden to disable ADC if ADC is already */
|
||||
/* disabled. */
|
||||
if (ADC_IS_ENABLE(hadc) != RESET)
|
||||
{
|
||||
/* Check if conditions to disable the ADC are fulfilled */
|
||||
if (ADC_DISABLING_CONDITIONS(hadc) != RESET)
|
||||
{
|
||||
/* Disable the ADC peripheral */
|
||||
__HAL_ADC_DISABLE(hadc);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Wait for ADC effectively disabled */
|
||||
/* Get tick count */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADEN))
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > ADC_DISABLE_TIMEOUT)
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return HAL status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Stop ADC conversion.
|
||||
* @note Prerequisite condition to use this function: ADC conversions must be
|
||||
* stopped to disable the ADC.
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status.
|
||||
*/
|
||||
static HAL_StatusTypeDef ADC_ConversionStop(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Verification if ADC is not already stopped on regular group to bypass */
|
||||
/* this function if not needed. */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc))
|
||||
{
|
||||
/* Stop potential conversion on going on regular group */
|
||||
/* Software is allowed to set ADSTP only when ADSTART=1 */
|
||||
if (HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADSTART) &&
|
||||
HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADEN))
|
||||
{
|
||||
/* Stop conversions on regular group */
|
||||
hadc->Instance->CR |= ADC_CR_ADSTP;
|
||||
}
|
||||
|
||||
/* Wait for conversion effectively stopped */
|
||||
/* Get tick count */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while((hadc->Instance->CR & ADC_CR_ADSTART) != RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > ADC_STOP_CONVERSION_TIMEOUT)
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Return HAL status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief DMA transfer complete callback.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void ADC_DMAConvCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Retrieve ADC handle corresponding to current DMA handle */
|
||||
ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
|
||||
|
||||
/* Update state machine on conversion status if not in error state */
|
||||
if (HAL_IS_BIT_CLR(hadc->State, HAL_ADC_STATE_ERROR_INTERNAL | HAL_ADC_STATE_ERROR_DMA))
|
||||
{
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_REG_EOC);
|
||||
|
||||
/* Determine whether any further conversion upcoming on group regular */
|
||||
/* by external trigger, continuous mode or scan sequence on going. */
|
||||
if(ADC_IS_SOFTWARE_START_REGULAR(hadc) &&
|
||||
(hadc->Init.ContinuousConvMode == DISABLE) )
|
||||
{
|
||||
/* If End of Sequence is reached, disable interrupts */
|
||||
if( __HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOS) )
|
||||
{
|
||||
/* Allowed to modify bits ADC_IT_EOC/ADC_IT_EOS only if bit */
|
||||
/* ADSTART==0 (no conversion on going) */
|
||||
if (ADC_IS_CONVERSION_ONGOING_REGULAR(hadc) == RESET)
|
||||
{
|
||||
/* Disable ADC end of single conversion interrupt on group regular */
|
||||
/* Note: Overrun interrupt was enabled with EOC interrupt in */
|
||||
/* HAL_Start_IT(), but is not disabled here because can be used */
|
||||
/* by overrun IRQ process below. */
|
||||
__HAL_ADC_DISABLE_IT(hadc, ADC_IT_EOC | ADC_IT_EOS);
|
||||
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_READY);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Change ADC state to error state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
/* Set ADC error code to ADC IP internal error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_INTERNAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Conversion complete callback */
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->ConvCpltCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_ConvCpltCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call DMA error callback */
|
||||
hadc->DMA_Handle->XferErrorCallback(hdma);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA half transfer complete callback.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void ADC_DMAHalfConvCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Retrieve ADC handle corresponding to current DMA handle */
|
||||
ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
|
||||
|
||||
/* Half conversion callback */
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->ConvHalfCpltCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_ConvHalfCpltCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA error callback
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void ADC_DMAError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Retrieve ADC handle corresponding to current DMA handle */
|
||||
ADC_HandleTypeDef* hadc = ( ADC_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
|
||||
|
||||
/* Set ADC state */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_DMA);
|
||||
|
||||
/* Set ADC error code to DMA error */
|
||||
SET_BIT(hadc->ErrorCode, HAL_ADC_ERROR_DMA);
|
||||
|
||||
/* Error callback */
|
||||
#if (USE_HAL_ADC_REGISTER_CALLBACKS == 1)
|
||||
hadc->ErrorCallback(hadc);
|
||||
#else
|
||||
HAL_ADC_ErrorCallback(hadc);
|
||||
#endif /* USE_HAL_ADC_REGISTER_CALLBACKS */
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Perform an ADC automatic self-calibration
|
||||
* Calibration prerequisite: ADC must be disabled (execute this
|
||||
* function before HAL_ADC_Start() or after HAL_ADC_Stop() ).
|
||||
* @note Calibration factor can be read after calibration, using function
|
||||
* HAL_ADC_GetValue() (value on 7 bits: from DR[6;0]).
|
||||
* @param hadc ADC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_ADC_Calibration_Start(ADC_HandleTypeDef* hadc)
|
||||
{
|
||||
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
|
||||
uint32_t tickstart = 0U;
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
uint32_t backup_setting_adc_dma_transfer = 0; /* Note: Variable not declared as volatile because register read is already declared as volatile */
|
||||
#endif
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hadc);
|
||||
|
||||
/* Calibration prerequisite: ADC must be disabled. */
|
||||
if (ADC_IS_ENABLE(hadc) == RESET)
|
||||
{
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_REG_BUSY,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL);
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/* Disable ADC DMA transfer request during calibration */
|
||||
/* Note: Specificity of this PY32 serie: Calibration factor is */
|
||||
/* available in data register and also transfered by DMA. */
|
||||
/* To not insert ADC calibration factor among ADC conversion data */
|
||||
/* in array variable, DMA transfer must be disabled during */
|
||||
/* calibration. */
|
||||
backup_setting_adc_dma_transfer = READ_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
|
||||
CLEAR_BIT(hadc->Instance->CFGR1, ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG);
|
||||
#endif
|
||||
|
||||
/* Start ADC calibration */
|
||||
hadc->Instance->CR |= ADC_CR_ADCAL;
|
||||
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for calibration completion */
|
||||
while(HAL_IS_BIT_SET(hadc->Instance->CR, ADC_CR_ADCAL))
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > ADC_CALIBRATION_TIMEOUT)
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL,
|
||||
HAL_ADC_STATE_ERROR_INTERNAL);
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/* Restore ADC DMA transfer request after calibration */
|
||||
SET_BIT(hadc->Instance->CFGR1, backup_setting_adc_dma_transfer);
|
||||
#endif
|
||||
|
||||
/* Set ADC state */
|
||||
ADC_STATE_CLR_SET(hadc->State,
|
||||
HAL_ADC_STATE_BUSY_INTERNAL,
|
||||
HAL_ADC_STATE_RESET);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update ADC state machine to error */
|
||||
SET_BIT(hadc->State, HAL_ADC_STATE_ERROR_CONFIG);
|
||||
|
||||
tmp_hal_status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hadc);
|
||||
|
||||
/* Return function status */
|
||||
return tmp_hal_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_adc_ex.c
|
||||
* @author MCU Application Team
|
||||
* @brief This file provides firmware functions to manage the following
|
||||
* functionalities of the Analog to Digital Convertor (ADC)
|
||||
* peripheral:
|
||||
* + Operation functions
|
||||
* ++ Calibration (ADC automatic self-calibration)
|
||||
* Other functions (generic functions) are available in file
|
||||
* "py32f0xx_hal_adc.c".
|
||||
*
|
||||
@verbatim
|
||||
[..]
|
||||
(@) Sections "ADC peripheral features" and "How to use this driver" are
|
||||
available in file of generic functions "py32f0xx_hal_adc.c".
|
||||
[..]
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 ADCEx ADCEx
|
||||
* @brief ADC HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Private macros -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup ADCEx_Exported_Functions ADCEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup ADCEx_Exported_Functions_Group1 Extended Initialization/de-initialization functions
|
||||
* @brief Extended Initialization and Configuration functions
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
1025
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_comp.c
Normal file
1025
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_comp.c
Normal file
@@ -0,0 +1,1025 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_comp.c
|
||||
* @author MCU Application Team
|
||||
* @brief COMP HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the COMP peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Start/Stop operation functions in polling mode
|
||||
* + Start/Stop operation functions in interrupt mode (through EXTI interrupt)
|
||||
* + Peripheral control functions
|
||||
* + Peripheral state functions
|
||||
*
|
||||
@verbatim
|
||||
================================================================================
|
||||
##### COMP Peripheral features #####
|
||||
================================================================================
|
||||
|
||||
[..]
|
||||
The PY32F0xx device family integrates two analog comparators instances:
|
||||
COMP1, COMP2.
|
||||
(#) Comparators input minus (inverting input) and input plus (non inverting input)
|
||||
can be set to internal references or to GPIO pins
|
||||
(refer to GPIO list in reference manual).
|
||||
|
||||
(#) Comparators output level is available using HAL_COMP_GetOutputLevel()
|
||||
and can be redirected to other peripherals: GPIO pins (in mode
|
||||
alternate functions for comparator), timers.
|
||||
(refer to GPIO list in reference manual).
|
||||
|
||||
(#) The comparators have interrupt capability through the EXTI controller
|
||||
with wake-up from sleep and stop modes.
|
||||
|
||||
(#) Pairs of comparators instances can be combined in window mode
|
||||
(2 consecutive instances odd and even COMP<x> and COMP<x+1>).
|
||||
|
||||
From the corresponding IRQ handler, the right interrupt source can be retrieved
|
||||
using macro __HAL_COMP_COMPx_EXTI_GET_FLAG().
|
||||
|
||||
##### How to use this driver #####
|
||||
================================================================================
|
||||
[..]
|
||||
This driver provides functions to configure and program the comparator instances
|
||||
of PY32F0xx devices.
|
||||
|
||||
To use the comparator, perform the following steps:
|
||||
|
||||
(#) Initialize the COMP low level resources by implementing the HAL_COMP_MspInit():
|
||||
(++) Configure the GPIO connected to comparator inputs plus and minus in analog mode
|
||||
using HAL_GPIO_Init().
|
||||
(++) If needed, configure the GPIO connected to comparator output in alternate function mode
|
||||
using HAL_GPIO_Init().
|
||||
(++) If required enable the COMP interrupt by configuring and enabling EXTI line in Interrupt mode and
|
||||
selecting the desired sensitivity level using HAL_GPIO_Init() function. After that enable the comparator
|
||||
interrupt vector using HAL_NVIC_EnableIRQ() function.
|
||||
|
||||
(#) Configure the comparator using HAL_COMP_Init() function:
|
||||
(++) Select the input minus (inverting input)
|
||||
(++) Select the input plus (non-inverting input)
|
||||
(++) Select the hysteresis
|
||||
(++) Select the blanking source
|
||||
(++) Select the output polarity
|
||||
(++) Select the power mode
|
||||
(++) Select the window mode
|
||||
|
||||
-@@- HAL_COMP_Init() calls internally __HAL_RCC_SYSCFG_CLK_ENABLE()
|
||||
to enable internal control clock of the comparators.
|
||||
However, this is a legacy strategy. In future PY32 families,
|
||||
COMP clock enable must be implemented by user in "HAL_COMP_MspInit()".
|
||||
Therefore, for compatibility anticipation, it is recommended to
|
||||
implement __HAL_RCC_SYSCFG_CLK_ENABLE() in "HAL_COMP_MspInit()".
|
||||
|
||||
(#) Reconfiguration on-the-fly of comparator can be done by calling again
|
||||
function HAL_COMP_Init() with new input structure parameters values.
|
||||
|
||||
(#) Enable the comparator using HAL_COMP_Start() function.
|
||||
|
||||
(#) Use HAL_COMP_TriggerCallback() or HAL_COMP_GetOutputLevel() functions
|
||||
to manage comparator outputs (events and output level).
|
||||
|
||||
(#) Disable the comparator using HAL_COMP_Stop() function.
|
||||
|
||||
(#) De-initialize the comparator using HAL_COMP_DeInit() function.
|
||||
|
||||
(#) For safety purpose, comparator configuration can be locked using HAL_COMP_Lock() function.
|
||||
The only way to unlock the comparator is a device hardware reset.
|
||||
|
||||
*** Callback registration ***
|
||||
=============================================
|
||||
[..]
|
||||
|
||||
The compilation flag USE_HAL_COMP_REGISTER_CALLBACKS, when set to 1,
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
Use Functions @ref HAL_COMP_RegisterCallback()
|
||||
to register an interrupt callback.
|
||||
[..]
|
||||
|
||||
Function @ref HAL_COMP_RegisterCallback() allows to register following callbacks:
|
||||
(+) TriggerCallback : callback for COMP trigger.
|
||||
(+) MspInitCallback : callback for Msp Init.
|
||||
(+) MspDeInitCallback : callback for Msp DeInit.
|
||||
This function takes as parameters the HAL peripheral handle, the Callback ID
|
||||
and a pointer to the user callback function.
|
||||
[..]
|
||||
|
||||
Use function @ref HAL_COMP_UnRegisterCallback to reset a callback to the default
|
||||
weak function.
|
||||
[..]
|
||||
|
||||
@ref HAL_COMP_UnRegisterCallback takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
This function allows to reset following callbacks:
|
||||
(+) TriggerCallback : callback for COMP trigger.
|
||||
(+) MspInitCallback : callback for Msp Init.
|
||||
(+) MspDeInitCallback : callback for Msp DeInit.
|
||||
[..]
|
||||
|
||||
By default, after the @ref HAL_COMP_Init() and when the state is @ref HAL_COMP_STATE_RESET
|
||||
all callbacks are set to the corresponding weak functions:
|
||||
example @ref HAL_COMP_TriggerCallback().
|
||||
Exception done for MspInit and MspDeInit functions that are
|
||||
reset to the legacy weak functions in the @ref HAL_COMP_Init()/ @ref HAL_COMP_DeInit() only when
|
||||
these callbacks are null (not registered beforehand).
|
||||
[..]
|
||||
|
||||
If MspInit or MspDeInit are not null, the @ref HAL_COMP_Init()/ @ref HAL_COMP_DeInit()
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
|
||||
[..]
|
||||
|
||||
Callbacks can be registered/unregistered in @ref HAL_COMP_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit functions that can be registered/unregistered
|
||||
in @ref HAL_COMP_STATE_READY or @ref HAL_COMP_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 @ref HAL_COMP_RegisterCallback() before calling @ref HAL_COMP_DeInit()
|
||||
or @ref HAL_COMP_Init() function.
|
||||
[..]
|
||||
|
||||
When the compilation flag USE_HAL_COMP_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available and all callbacks
|
||||
are set to the corresponding weak functions.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_COMP_MODULE_ENABLED
|
||||
|
||||
|
||||
|
||||
/** @defgroup COMP COMP
|
||||
* @brief COMP HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @addtogroup COMP_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Delay for COMP startup time. */
|
||||
/* Note: Delay required to reach propagation delay specification. */
|
||||
/* Literal set to maximum value (refer to device datasheet, */
|
||||
/* parameter "tSTART"). */
|
||||
/* Unit: us */
|
||||
#define COMP_DELAY_STARTUP_US (80UL) /*!< Delay for COMP startup time */
|
||||
|
||||
/* Delay for COMP voltage scaler stabilization time. */
|
||||
/* Literal set to maximum value (refer to device datasheet, */
|
||||
/* parameter "tSTART_SCALER"). */
|
||||
/* Unit: us */
|
||||
#define COMP_DELAY_VOLTAGE_SCALER_STAB_US (200UL) /*!< Delay for COMP voltage scaler stabilization time */
|
||||
|
||||
#define COMP_OUTPUT_LEVEL_BITOFFSET_POS (COMP_CSR_COMP_OUT_Pos)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup COMP_Exported_Functions COMP Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup COMP_Exported_Functions_Group1 Initialization/de-initialization functions
|
||||
* @brief Initialization and de-initialization functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions to initialize and de-initialize comparators
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the COMP according to the specified
|
||||
* parameters in the COMP_InitTypeDef and initialize the associated handle.
|
||||
* @note If the selected comparator is locked, initialization can't be performed.
|
||||
* To unlock the configuration, perform a system reset.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
uint32_t tmp_csr;
|
||||
uint32_t exti_line;
|
||||
uint32_t comp_voltage_scaler_initialized; /* Value "0" if comparator voltage scaler is not initialized */
|
||||
__IO uint32_t wait_loop_index = 0UL;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the COMP handle allocation and lock status */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else if(__HAL_COMP_IS_LOCKED(hcomp))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
assert_param(IS_COMP_INPUT_PLUS(hcomp->Instance, hcomp->Init.InputPlus));
|
||||
assert_param(IS_COMP_INPUT_MINUS(hcomp->Instance, hcomp->Init.InputMinus));
|
||||
assert_param(IS_COMP_OUTPUTPOL(hcomp->Init.OutputPol));
|
||||
assert_param(IS_COMP_POWERMODE(hcomp->Init.Mode));
|
||||
assert_param(IS_COMP_HYSTERESIS(hcomp->Init.Hysteresis));
|
||||
assert_param(IS_COMP_TRIGGERMODE(hcomp->Init.TriggerMode));
|
||||
assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
|
||||
|
||||
if(hcomp->State == HAL_COMP_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hcomp->Lock = HAL_UNLOCKED;
|
||||
|
||||
/* Set COMP error code to none */
|
||||
COMP_CLEAR_ERRORCODE(hcomp);
|
||||
|
||||
|
||||
#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
|
||||
/* Init the COMP Callback settings */
|
||||
hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
|
||||
|
||||
if (hcomp->MspInitCallback == NULL)
|
||||
{
|
||||
hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
/* Note: Internal control clock of the comparators must */
|
||||
/* be enabled in "HAL_COMP_MspInit()" */
|
||||
/* using "__HAL_RCC_SYSCFG_CLK_ENABLE()". */
|
||||
hcomp->MspInitCallback(hcomp);
|
||||
#else
|
||||
/* Init the low level hardware */
|
||||
/* Note: Internal control clock of the comparators must */
|
||||
/* be enabled in "HAL_COMP_MspInit()" */
|
||||
/* using "__HAL_RCC_SYSCFG_CLK_ENABLE()". */
|
||||
HAL_COMP_MspInit(hcomp);
|
||||
#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Memorize voltage scaler state before initialization */
|
||||
comp_voltage_scaler_initialized = READ_BIT(hcomp->Instance->CSR, (COMP_CSR_INMSEL_1 | COMP_CSR_INMSEL_0));
|
||||
|
||||
/* Set COMP parameters */
|
||||
tmp_csr = ( hcomp->Init.InputMinus
|
||||
| hcomp->Init.InputPlus
|
||||
| hcomp->Init.OutputPol
|
||||
| hcomp->Init.Mode
|
||||
);
|
||||
|
||||
/* Set parameters in COMP register */
|
||||
/* Note: Update all bits except read-only, lock and enable bits */
|
||||
MODIFY_REG(hcomp->Instance->CSR,
|
||||
COMP_CSR_LOCK | COMP_CSR_COMP_OUT | COMP_CSR_PWRMODE |
|
||||
COMP_CSR_POLARITY | COMP_CSR_WINMODE | COMP_CSR_INPSEL |
|
||||
COMP_CSR_INMSEL | COMP_CSR_EN,
|
||||
tmp_csr
|
||||
);
|
||||
|
||||
/* Set digital filter */
|
||||
if (hcomp->Init.DigitalFilter == 0)
|
||||
{
|
||||
/* Disable digital filter */
|
||||
CLEAR_BIT(hcomp->Instance->FR, COMP_FR_FLTEN);
|
||||
}else
|
||||
{
|
||||
WRITE_REG(hcomp->Instance->FR, (COMP_FR_FLTEN | ((hcomp->Init.DigitalFilter) << COMP_FR_FLTCNT_Pos)));
|
||||
}
|
||||
|
||||
/* Set Vrefint Scaler Enable */
|
||||
if ((hcomp->Init.InputMinus == COMP_INPUT_MINUS_1_4VREFINT) || (hcomp->Init.InputMinus == COMP_INPUT_MINUS_1_2VREFINT) || \
|
||||
(hcomp->Init.InputMinus == COMP_INPUT_MINUS_3_4VREFINT) || (hcomp->Init.InputMinus == COMP_INPUT_MINUS_VREFINT))
|
||||
{
|
||||
SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_SCALER_EN);
|
||||
}
|
||||
|
||||
/* Set comparator hysteresis mode */
|
||||
MODIFY_REG(COMP12_COMMON->CSR_ODD, COMP_CSR_HYST, hcomp->Init.Hysteresis);
|
||||
|
||||
/* Set window mode */
|
||||
/* Note: Window mode bit is located into 1 out of the 2 pairs of COMP */
|
||||
/* instances. Therefore, this function can update another COMP */
|
||||
/* instance that the one currently selected. */
|
||||
if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP1_INPUT_PLUS_COMMON)
|
||||
{
|
||||
CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
|
||||
SET_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
|
||||
}
|
||||
else if(hcomp->Init.WindowMode == COMP_WINDOWMODE_COMP2_INPUT_PLUS_COMMON)
|
||||
{
|
||||
SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
|
||||
CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
|
||||
CLEAR_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
|
||||
}
|
||||
|
||||
/* Delay for COMP scaler bridge voltage stabilization */
|
||||
/* Apply the delay if voltage scaler bridge is required and not already enabled */
|
||||
if ((READ_BIT(hcomp->Instance->CSR, (COMP_CSR_INMSEL_1 | COMP_CSR_INMSEL_0)) != 0UL) &&
|
||||
(comp_voltage_scaler_initialized == 0UL) )
|
||||
{
|
||||
/* Wait loop initialization and execution */
|
||||
/* Note: Variable divided by 2 to compensate partially */
|
||||
/* CPU processing cycles, scaling in us split to not */
|
||||
/* exceed 32 bits register capacity and handle low frequency. */
|
||||
wait_loop_index = ((COMP_DELAY_VOLTAGE_SCALER_STAB_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
|
||||
while(wait_loop_index != 0UL)
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the EXTI line corresponding to the selected COMP instance */
|
||||
exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
|
||||
|
||||
/* Manage EXTI settings */
|
||||
if((hcomp->Init.TriggerMode & (COMP_EXTI_IT | COMP_EXTI_EVENT)) != 0UL)
|
||||
{
|
||||
/* Configure EXTI rising edge */
|
||||
if((hcomp->Init.TriggerMode & COMP_EXTI_RISING) != 0UL)
|
||||
{
|
||||
LL_EXTI_EnableRisingTrig(exti_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_EXTI_DisableRisingTrig(exti_line);
|
||||
}
|
||||
|
||||
/* Configure EXTI falling edge */
|
||||
if((hcomp->Init.TriggerMode & COMP_EXTI_FALLING) != 0UL)
|
||||
{
|
||||
LL_EXTI_EnableFallingTrig(exti_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_EXTI_DisableFallingTrig(exti_line);
|
||||
}
|
||||
|
||||
/* Clear COMP EXTI pending bit (if any) */
|
||||
LL_EXTI_ClearFlag(exti_line);
|
||||
|
||||
/* Configure EXTI event mode */
|
||||
if((hcomp->Init.TriggerMode & COMP_EXTI_EVENT) != 0UL)
|
||||
{
|
||||
LL_EXTI_EnableEvent(exti_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_EXTI_DisableEvent(exti_line);
|
||||
}
|
||||
|
||||
/* Configure EXTI interrupt mode */
|
||||
if((hcomp->Init.TriggerMode & COMP_EXTI_IT) != 0UL)
|
||||
{
|
||||
LL_EXTI_EnableIT(exti_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_EXTI_DisableIT(exti_line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable EXTI event mode */
|
||||
LL_EXTI_DisableEvent(exti_line);
|
||||
|
||||
/* Disable EXTI interrupt mode */
|
||||
LL_EXTI_DisableIT(exti_line);
|
||||
}
|
||||
|
||||
/* Set HAL COMP handle state */
|
||||
/* Note: Transition from state reset to state ready, */
|
||||
/* otherwise (coming from state ready or busy) no state update. */
|
||||
if (hcomp->State == HAL_COMP_STATE_RESET)
|
||||
{
|
||||
hcomp->State = HAL_COMP_STATE_READY;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the COMP peripheral.
|
||||
* @note Deinitialization cannot be performed if the COMP configuration is locked.
|
||||
* To unlock the configuration, perform a system reset.
|
||||
* @note DeInitialize COMP1 may affect the hysteresis and Vrefint functions of COMP2.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_DeInit(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the COMP handle allocation and lock status */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else if(__HAL_COMP_IS_LOCKED(hcomp))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
/* Set COMP_CSR register to reset value */
|
||||
WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
|
||||
|
||||
#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
|
||||
if (hcomp->MspDeInitCallback == NULL)
|
||||
{
|
||||
hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
|
||||
}
|
||||
|
||||
/* DeInit the low level hardware: GPIO, RCC clock, NVIC */
|
||||
hcomp->MspDeInitCallback(hcomp);
|
||||
#else
|
||||
/* DeInit the low level hardware: GPIO, RCC clock, NVIC */
|
||||
HAL_COMP_MspDeInit(hcomp);
|
||||
#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
|
||||
|
||||
/* Set HAL COMP handle state */
|
||||
hcomp->State = HAL_COMP_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hcomp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the COMP MSP.
|
||||
* @param hcomp COMP handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_COMP_MspInit(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcomp);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_COMP_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the COMP MSP.
|
||||
* @param hcomp COMP handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_COMP_MspDeInit(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcomp);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_COMP_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User COMP Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified COMP.
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
|
||||
* @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
|
||||
* @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_RegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID, pCOMP_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (HAL_COMP_STATE_READY == hcomp->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_COMP_TRIGGER_CB_ID :
|
||||
hcomp->TriggerCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPINIT_CB_ID :
|
||||
hcomp->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPDEINIT_CB_ID :
|
||||
hcomp->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_COMP_STATE_RESET == hcomp->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_COMP_MSPINIT_CB_ID :
|
||||
hcomp->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPDEINIT_CB_ID :
|
||||
hcomp->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a COMP Callback
|
||||
* COMP callback is redirected to the weak predefined callback
|
||||
* @param hcomp Pointer to a COMP_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified COMP.
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_COMP_TRIGGER_CB_ID Trigger callback ID
|
||||
* @arg @ref HAL_COMP_MSPINIT_CB_ID MspInit callback ID
|
||||
* @arg @ref HAL_COMP_MSPDEINIT_CB_ID MspDeInit callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_UnRegisterCallback(COMP_HandleTypeDef *hcomp, HAL_COMP_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (HAL_COMP_STATE_READY == hcomp->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_COMP_TRIGGER_CB_ID :
|
||||
hcomp->TriggerCallback = HAL_COMP_TriggerCallback; /* Legacy weak callback */
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPINIT_CB_ID :
|
||||
hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPDEINIT_CB_ID :
|
||||
hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_COMP_STATE_RESET == hcomp->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_COMP_MSPINIT_CB_ID :
|
||||
hcomp->MspInitCallback = HAL_COMP_MspInit; /* Legacy weak MspInit */
|
||||
break;
|
||||
|
||||
case HAL_COMP_MSPDEINIT_CB_ID :
|
||||
hcomp->MspDeInitCallback = HAL_COMP_MspDeInit; /* Legacy weak MspDeInit */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hcomp->ErrorCode |= HAL_COMP_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup COMP_Exported_Functions_Group2 Start-Stop operation functions
|
||||
* @brief Start-Stop operation functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Start a comparator instance.
|
||||
(+) Stop a comparator instance.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the comparator.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_Start(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
__IO uint32_t wait_loop_index = 0UL;
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the COMP handle allocation and lock status */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else if(__HAL_COMP_IS_LOCKED(hcomp))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
if(hcomp->State == HAL_COMP_STATE_READY)
|
||||
{
|
||||
/* Enable the selected comparator */
|
||||
SET_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
|
||||
|
||||
/* Set HAL COMP handle state */
|
||||
hcomp->State = HAL_COMP_STATE_BUSY;
|
||||
|
||||
/* Delay for COMP startup time */
|
||||
/* Wait loop initialization and execution */
|
||||
/* Note: Variable divided by 2 to compensate partially */
|
||||
/* CPU processing cycles, scaling in us split to not */
|
||||
/* exceed 32 bits register capacity and handle low frequency. */
|
||||
wait_loop_index = ((COMP_DELAY_STARTUP_US / 10UL) * (SystemCoreClock / (100000UL * 2UL)));
|
||||
while(wait_loop_index != 0UL)
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the comparator.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_Stop(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the COMP handle allocation and lock status */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else if(__HAL_COMP_IS_LOCKED(hcomp))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
/* Check compliant states: HAL_COMP_STATE_READY or HAL_COMP_STATE_BUSY */
|
||||
/* (all states except HAL_COMP_STATE_RESET and except locked status. */
|
||||
if(hcomp->State != HAL_COMP_STATE_RESET)
|
||||
{
|
||||
/* Disable the selected comparator */
|
||||
CLEAR_BIT(hcomp->Instance->CSR, COMP_CSR_EN);
|
||||
|
||||
/* Set HAL COMP handle state */
|
||||
hcomp->State = HAL_COMP_STATE_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Comparator IRQ handler.
|
||||
* @param hcomp COMP handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_COMP_IRQHandler(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Get the EXTI line corresponding to the selected COMP instance */
|
||||
uint32_t exti_line = COMP_GET_EXTI_LINE(hcomp->Instance);
|
||||
uint32_t comparator_window_mode_odd = READ_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_WINMODE);
|
||||
uint32_t comparator_window_mode_even = READ_BIT(COMP12_COMMON->CSR_EVEN, COMP_CSR_WINMODE);
|
||||
|
||||
/* Check COMP EXTI flag */
|
||||
if(LL_EXTI_IsActiveFlag(exti_line) != 0UL)
|
||||
{
|
||||
/* Check whether comparator is in independent or window mode */
|
||||
if( (comparator_window_mode_odd != 0UL)
|
||||
|| (comparator_window_mode_even != 0UL))
|
||||
{
|
||||
/* Clear COMP EXTI line pending bit of the pair of comparators */
|
||||
/* in window mode. */
|
||||
/* Note: Pair of comparators in window mode can both trig IRQ when */
|
||||
/* input voltage is changing from "out of window" area */
|
||||
/* (low or high ) to the other "out of window" area (high or low).*/
|
||||
/* Both flags must be cleared to call comparator trigger */
|
||||
/* callback is called once. */
|
||||
LL_EXTI_ClearFlag((COMP_EXTI_LINE_COMP1 | COMP_EXTI_LINE_COMP2));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear COMP EXTI line pending bit */
|
||||
LL_EXTI_ClearFlag(exti_line);
|
||||
}
|
||||
|
||||
/* COMP trigger user callback */
|
||||
#if (USE_HAL_COMP_REGISTER_CALLBACKS == 1)
|
||||
hcomp->TriggerCallback(hcomp);
|
||||
#else
|
||||
HAL_COMP_TriggerCallback(hcomp);
|
||||
#endif /* USE_HAL_COMP_REGISTER_CALLBACKS */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup COMP_Exported_Functions_Group3 Peripheral Control functions
|
||||
* @brief Management functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the comparators.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Lock the selected comparator configuration.
|
||||
* @note A system reset is required to unlock the comparator configuration.
|
||||
* @note Locking the comparator from reset state is possible
|
||||
* if __HAL_RCC_SYSCFG_CLK_ENABLE() is being called before.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_COMP_Lock(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the COMP handle allocation and lock status */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else if(__HAL_COMP_IS_LOCKED(hcomp))
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
/* Set HAL COMP handle state */
|
||||
switch(hcomp->State)
|
||||
{
|
||||
case HAL_COMP_STATE_RESET:
|
||||
hcomp->State = HAL_COMP_STATE_RESET_LOCKED;
|
||||
break;
|
||||
case HAL_COMP_STATE_READY:
|
||||
hcomp->State = HAL_COMP_STATE_READY_LOCKED;
|
||||
break;
|
||||
default: /* HAL_COMP_STATE_BUSY */
|
||||
hcomp->State = HAL_COMP_STATE_BUSY_LOCKED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Set the lock bit corresponding to selected comparator */
|
||||
__HAL_COMP_LOCK(hcomp);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the output level (high or low) of the selected comparator.
|
||||
* The output level depends on the selected polarity.
|
||||
* If the polarity is not inverted:
|
||||
* - Comparator output is low when the input plus is at a lower
|
||||
* voltage than the input minus
|
||||
* - Comparator output is high when the input plus is at a higher
|
||||
* voltage than the input minus
|
||||
* If the polarity is inverted:
|
||||
* - Comparator output is high when the input plus is at a lower
|
||||
* voltage than the input minus
|
||||
* - Comparator output is low when the input plus is at a higher
|
||||
* voltage than the input minus
|
||||
* @param hcomp COMP handle
|
||||
* @retval Returns the selected comparator output level:
|
||||
* @arg COMP_OUTPUT_LEVEL_LOW
|
||||
* @arg COMP_OUTPUT_LEVEL_HIGH
|
||||
*
|
||||
*/
|
||||
uint32_t HAL_COMP_GetOutputLevel(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
return (uint32_t)(READ_BIT(hcomp->Instance->CSR, COMP_CSR_COMP_OUT)
|
||||
>> COMP_OUTPUT_LEVEL_BITOFFSET_POS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Comparator trigger callback.
|
||||
* @param hcomp COMP handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_COMP_TriggerCallback(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcomp);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_COMP_TriggerCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup COMP_Exported_Functions_Group4 Peripheral State functions
|
||||
* @brief Peripheral State functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection permit to get in run-time the status of the peripheral.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the COMP handle state.
|
||||
* @param hcomp COMP handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_COMP_StateTypeDef HAL_COMP_GetState(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Check the COMP handle allocation */
|
||||
if(hcomp == NULL)
|
||||
{
|
||||
return HAL_COMP_STATE_RESET;
|
||||
}
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
/* Return HAL COMP handle state */
|
||||
return hcomp->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the COMP error code.
|
||||
* @param hcomp COMP handle
|
||||
* @retval COMP error code
|
||||
*/
|
||||
uint32_t HAL_COMP_GetError(COMP_HandleTypeDef *hcomp)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
|
||||
|
||||
return hcomp->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif /* HAL_COMP_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
340
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_cortex.c
Normal file
340
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_cortex.c
Normal file
@@ -0,0 +1,340 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_cortex.c
|
||||
* @author MCU Application Team
|
||||
* @brief CORTEX HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the CORTEX:
|
||||
* + Initialization and Configuration functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
*** How to configure Interrupts using CORTEX HAL driver ***
|
||||
===========================================================
|
||||
[..]
|
||||
This section provides functions allowing to configure the NVIC interrupts (IRQ).
|
||||
The Cortex M0+ exceptions are managed by CMSIS functions.
|
||||
(#) Enable and Configure the priority of the selected IRQ Channels.
|
||||
The priority can be 0..3.
|
||||
|
||||
-@- Lower priority values gives higher priority.
|
||||
-@- Priority Order:
|
||||
(#@) Lowest priority.
|
||||
(#@) Lowest hardware priority (IRQn position).
|
||||
|
||||
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
|
||||
|
||||
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
|
||||
|
||||
-@- Negative value of IRQn_Type are not allowed.
|
||||
|
||||
*** How to configure Systick using CORTEX HAL driver ***
|
||||
========================================================
|
||||
[..]
|
||||
Setup SysTick Timer for time base.
|
||||
|
||||
(+) The HAL_SYSTICK_Config()function calls the SysTick_Config() function which
|
||||
is a CMSIS function that:
|
||||
(++) Configures the SysTick Reload register with value passed as function parameter.
|
||||
(++) Configures the SysTick IRQ priority to the lowest value (0x03).
|
||||
(++) Resets the SysTick Counter register.
|
||||
(++) Configures the SysTick Counter clock source to be Core Clock Source (HCLK).
|
||||
(++) Enables the SysTick Interrupt.
|
||||
(++) Starts the SysTick Counter.
|
||||
|
||||
(+) You can change the SysTick Clock source to be HCLK_Div8 by calling the macro
|
||||
__HAL_CORTEX_SYSTICKCLK_CONFIG(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
|
||||
HAL_SYSTICK_Config() function call. The __HAL_CORTEX_SYSTICKCLK_CONFIG() macro is defined
|
||||
inside the py32f0xx_hal_cortex.h file.
|
||||
|
||||
(+) You can change the SysTick IRQ priority by calling the
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
|
||||
call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
|
||||
|
||||
(+) To adjust the SysTick time base, use the following formula:
|
||||
|
||||
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
|
||||
(++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
|
||||
(++) Reload Value should not exceed 0xFFFFFF
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CORTEX
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions_Group1
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides the CORTEX HAL driver functions allowing to configure Interrupts
|
||||
Systick functionalities
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets the priority of an interrupt.
|
||||
* @param IRQn External interrupt number .
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
*
|
||||
* @param PreemptPriority The preemption priority for the IRQn channel.
|
||||
* This parameter can be a value between 0 and 3.
|
||||
* A lower priority value indicates a higher priority
|
||||
* @param SubPriority the subpriority level for the IRQ channel.
|
||||
* with py32f0xx devices, this parameter is a dummy value and it is ignored, because
|
||||
* no subpriority supported in Cortex M0+ based products.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||
NVIC_SetPriority(IRQn,PreemptPriority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable a device specific interrupt in the NVIC interrupt controller.
|
||||
* @param IRQn External interrupt number.
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||
|
||||
/* Enable interrupt */
|
||||
NVIC_EnableIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable a device specific interrupt in the NVIC interrupt controller.
|
||||
* @param IRQn External interrupt number.
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (py32f0xx.h))
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||
|
||||
/* Disable interrupt */
|
||||
NVIC_DisableIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initiate a system reset request to reset the MCU.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SystemReset(void)
|
||||
{
|
||||
/* System Reset */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the System Timer with interrupt enabled and start the System Tick Timer (SysTick):
|
||||
* Counter is in free running mode to generate periodic interrupts.
|
||||
* @param TicksNumb Specifies the ticks Number of ticks between two interrupts.
|
||||
* @retval status: - 0 Function succeeded.
|
||||
* - 1 Function failed.
|
||||
*/
|
||||
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
|
||||
{
|
||||
return SysTick_Config(TicksNumb);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup CORTEX_Exported_Functions_Group2
|
||||
* @brief Cortex control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the CORTEX
|
||||
(NVIC, SYSTICK, MPU) functionalities.
|
||||
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get the priority of an interrupt.
|
||||
* @param IRQn External interrupt number.
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (py32f0xx.h))
|
||||
* @retval None
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
/* Get priority for Cortex-M system or device specific interrupts */
|
||||
return NVIC_GetPriority(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Pending bit of an external interrupt.
|
||||
* @param IRQn External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (py32f0xx.h))
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||
|
||||
/* Set interrupt pending */
|
||||
NVIC_SetPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get Pending Interrupt (read the pending register in the NVIC
|
||||
* and return the pending bit for the specified interrupt).
|
||||
* @param IRQn External interrupt number.
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (py32f0xx.h))
|
||||
* @retval status: - 0 Interrupt status is not pending.
|
||||
* - 1 Interrupt status is pending.
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||
|
||||
/* Return 1 if pending else 0 */
|
||||
return NVIC_GetPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear the pending bit of an external interrupt.
|
||||
* @param IRQn External interrupt number.
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete PY32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (py32f0xx.h))
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_DEVICE_IRQ(IRQn));
|
||||
|
||||
/* Clear pending interrupt */
|
||||
NVIC_ClearPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the SysTick clock source.
|
||||
* @param CLKSource specifies the SysTick clock source.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg SYSTICK_CLKSOURCE_HCLK_DIV8: AHB clock divided by 8 selected as SysTick clock source.
|
||||
* @arg SYSTICK_CLKSOURCE_HCLK: AHB clock selected as SysTick clock source.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
|
||||
if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
|
||||
{
|
||||
SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;
|
||||
}
|
||||
else
|
||||
{
|
||||
SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle SYSTICK interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_SYSTICK_IRQHandler(void)
|
||||
{
|
||||
HAL_SYSTICK_Callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SYSTICK callback.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_SYSTICK_Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_SYSTICK_Callback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
333
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_crc.c
Normal file
333
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_crc.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_crc.c
|
||||
* @author MCU Application Team
|
||||
* @brief CRC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Cyclic Redundancy Check (CRC) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
* + Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### How to use this driver #####
|
||||
===============================================================================
|
||||
[..]
|
||||
(+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
|
||||
(+) Initialize CRC calculator
|
||||
(++) specify generating polynomial (peripheral default or non-default one)
|
||||
(++) specify initialization value (peripheral default or non-default one)
|
||||
(++) specify input data format
|
||||
(++) specify input or output data inversion mode if any
|
||||
(+) Use HAL_CRC_Accumulate() function to compute the CRC value of the
|
||||
input data buffer starting with the previously computed CRC as
|
||||
initialization value
|
||||
(+) Use HAL_CRC_Calculate() function to compute the CRC value of the
|
||||
input data buffer starting with the defined initialization value
|
||||
(default or non-default) to initiate CRC calculation
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 CRC CRC
|
||||
* @brief CRC HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions CRC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the CRC according to the specified parameters
|
||||
in the CRC_InitTypeDef and create the associated handle
|
||||
(+) DeInitialize the CRC peripheral
|
||||
(+) Initialize the CRC MSP (MCU Specific Package)
|
||||
(+) DeInitialize the CRC MSP
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the CRC according to the specified
|
||||
* parameters in the CRC_InitTypeDef and create the associated handle.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Check the CRC handle allocation */
|
||||
if (hcrc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
|
||||
|
||||
if (hcrc->State == HAL_CRC_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hcrc->Lock = HAL_UNLOCKED;
|
||||
/* Init the low level hardware */
|
||||
HAL_CRC_MspInit(hcrc);
|
||||
}
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the CRC peripheral.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Check the CRC handle allocation */
|
||||
if (hcrc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
|
||||
|
||||
/* Check the CRC peripheral state */
|
||||
if (hcrc->State == HAL_CRC_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Reset CRC calculation unit */
|
||||
__HAL_CRC_DR_RESET(hcrc);
|
||||
|
||||
/* Reset IDR register content */
|
||||
CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
|
||||
|
||||
/* DeInit the low level hardware */
|
||||
HAL_CRC_MspDeInit(hcrc);
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_RESET;
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hcrc);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the CRC MSP.
|
||||
* @param hcrc CRC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcrc);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_CRC_MspInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the CRC MSP.
|
||||
* @param hcrc CRC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcrc);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_CRC_MspDeInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief management functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) compute the 32-bit CRC value of a 32-bit data buffer
|
||||
using combination of the previous CRC value and the new one.
|
||||
|
||||
[..] or
|
||||
|
||||
(+) compute the 32-bit CRC value of a 32-bit data buffer
|
||||
independently of the previous CRC value.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Compute the 32-bit CRC value of a 32-bit data buffer
|
||||
* starting with the previously computed CRC as initialization value.
|
||||
* @param hcrc CRC handle
|
||||
* @param pBuffer pointer to the input data buffer.
|
||||
* @param BufferLength input data buffer length (number of uint32_t words).
|
||||
* @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*/
|
||||
uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
|
||||
{
|
||||
uint32_t index; /* CRC input data buffer index */
|
||||
uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Enter Data to the CRC calculator */
|
||||
for (index = 0U; index < BufferLength; index++)
|
||||
{
|
||||
hcrc->Instance->DR = pBuffer[index];
|
||||
}
|
||||
temp = hcrc->Instance->DR;
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return the CRC computed value */
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute the 32-bit CRC value of a 32-bit data buffer
|
||||
* starting with hcrc->Instance->INIT as initialization value.
|
||||
* @param hcrc CRC handle
|
||||
* @param pBuffer pointer to the input data buffer.
|
||||
* @param BufferLength input data buffer length (number of uint32_t words).
|
||||
* @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*/
|
||||
uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
|
||||
{
|
||||
uint32_t index; /* CRC input data buffer index */
|
||||
uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is
|
||||
* written in hcrc->Instance->DR) */
|
||||
__HAL_CRC_DR_RESET(hcrc);
|
||||
|
||||
/* Enter 32-bit input data to the CRC calculator */
|
||||
for (index = 0U; index < BufferLength; index++)
|
||||
{
|
||||
hcrc->Instance->DR = pBuffer[index];
|
||||
}
|
||||
temp = hcrc->Instance->DR;
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return the CRC computed value */
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
|
||||
* @brief Peripheral State functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection permits to get in run-time the status of the peripheral.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the CRC handle state.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Return CRC handle state */
|
||||
return hcrc->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
894
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_dma.c
Normal file
894
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_dma.c
Normal file
@@ -0,0 +1,894 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_dma.c
|
||||
* @author MCU Application Team
|
||||
* @brief DMA HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Direct Memory Access (DMA) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral State and errors functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Enable and configure the peripheral to be connected to the DMA Channel
|
||||
(except for internal SRAM / FLASH memories: no initialization is
|
||||
necessary). Please refer to the Reference manual for connection between peripherals
|
||||
and DMA requests.
|
||||
|
||||
(#) For a given Channel, program the required configuration through the following parameters:
|
||||
Channel request, Transfer Direction, Source and Destination data formats,
|
||||
Circular or Normal mode, Channel Priority level, Source and Destination Increment mode
|
||||
using HAL_DMA_Init() function.
|
||||
|
||||
(#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
|
||||
detection.
|
||||
|
||||
(#) Use HAL_DMA_Abort() function to abort the current transfer
|
||||
|
||||
-@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
|
||||
*** Polling mode IO operation ***
|
||||
=================================
|
||||
[..]
|
||||
(+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
|
||||
address and destination address and the Length of data to be transferred
|
||||
(+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
|
||||
case a fixed Timeout can be configured by User depending from his application.
|
||||
|
||||
*** Interrupt mode IO operation ***
|
||||
===================================
|
||||
[..]
|
||||
(+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
|
||||
(+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
|
||||
(+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
|
||||
Source address and destination address and the Length of data to be transferred.
|
||||
In this case the DMA interrupt is configured
|
||||
(+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
|
||||
(+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
|
||||
add his own function by customization of function pointer XferCpltCallback and
|
||||
XferErrorCallback (i.e. a member of DMA handle structure).
|
||||
|
||||
*** DMA HAL driver macros list ***
|
||||
=============================================
|
||||
[..]
|
||||
Below the list of most used macros in DMA HAL driver.
|
||||
|
||||
(+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
|
||||
(+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
|
||||
(+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
|
||||
(+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
|
||||
(+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
|
||||
(+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
|
||||
(+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
|
||||
|
||||
[..]
|
||||
(@) You can refer to the DMA HAL driver header file for more useful macros
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 DMA DMA
|
||||
* @brief DMA HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup DMA_Private_Functions DMA Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions DMA Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and de-initialization functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to initialize the DMA Channel source
|
||||
and destination addresses, incrementation and data sizes, transfer direction,
|
||||
circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
|
||||
[..]
|
||||
The HAL_DMA_Init() function follows the DMA configuration procedures as described in
|
||||
reference manual.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the DMA according to the specified
|
||||
* parameters in the DMA_InitTypeDef and initialize the associated handle.
|
||||
* @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Check the DMA handle allocation */
|
||||
if(hdma == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
|
||||
assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
|
||||
assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
|
||||
assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
|
||||
assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
|
||||
assert_param(IS_DMA_MODE(hdma->Init.Mode));
|
||||
assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
|
||||
|
||||
|
||||
/* DMA */
|
||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||
hdma->DmaBaseAddress = DMA1;
|
||||
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
|
||||
/* Get the CCR register value */
|
||||
tmp = hdma->Instance->CCR;
|
||||
|
||||
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
|
||||
tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
|
||||
DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
|
||||
DMA_CCR_DIR));
|
||||
|
||||
/* Prepare the DMA Channel configuration */
|
||||
tmp |= hdma->Init.Direction |
|
||||
hdma->Init.PeriphInc | hdma->Init.MemInc |
|
||||
hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
|
||||
hdma->Init.Mode | hdma->Init.Priority;
|
||||
|
||||
/* Write to DMA Channel CR register */
|
||||
hdma->Instance->CCR = tmp;
|
||||
|
||||
/* Initialise the error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Initialize the DMA state*/
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
/* Allocate lock resource and initialize it */
|
||||
hdma->Lock = HAL_UNLOCKED;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the DMA peripheral.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Check the DMA handle allocation */
|
||||
if(hdma == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
/* Disable the selected DMA Channelx */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Reset DMA Channel control register */
|
||||
hdma->Instance->CCR = 0U;
|
||||
|
||||
/* Reset DMA Channel Number of Data to Transfer register */
|
||||
hdma->Instance->CNDTR = 0U;
|
||||
|
||||
/* Reset DMA Channel peripheral address register */
|
||||
hdma->Instance->CPAR = 0U;
|
||||
|
||||
/* Reset DMA Channel memory address register */
|
||||
hdma->Instance->CMAR = 0U;
|
||||
|
||||
|
||||
hdma->ChannelIndex = (((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1)) << 2;
|
||||
hdma->DmaBaseAddress = DMA1;
|
||||
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << (hdma->ChannelIndex));
|
||||
|
||||
/* Clean all callbacks */
|
||||
hdma->XferCpltCallback = NULL;
|
||||
hdma->XferHalfCpltCallback = NULL;
|
||||
hdma->XferErrorCallback = NULL;
|
||||
hdma->XferAbortCallback = NULL;
|
||||
|
||||
/* Reset the error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Reset the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
||||
* @brief Input and Output operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure the source, destination address and data length and Start DMA transfer
|
||||
(+) Configure the source, destination address and data length and
|
||||
Start DMA transfer with interrupt
|
||||
(+) Abort DMA transfer
|
||||
(+) Poll for transfer complete
|
||||
(+) Handle DMA interrupt request
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the DMA Transfer.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
if(HAL_DMA_STATE_READY == hdma->State)
|
||||
{
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Configure the source, destination address and the data length & clear flags*/
|
||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_DMA_ENABLE(hdma);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
status = HAL_BUSY;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the DMA Transfer with interrupt enabled.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
if(HAL_DMA_STATE_READY == hdma->State)
|
||||
{
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Configure the source, destination address and the data length & clear flags*/
|
||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||
|
||||
/* Enable the transfer complete interrupt */
|
||||
/* Enable the transfer Error interrupt */
|
||||
if(NULL != hdma->XferHalfCpltCallback)
|
||||
{
|
||||
/* Enable the Half transfer complete interrupt as well */
|
||||
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||
}
|
||||
else
|
||||
{
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
||||
__HAL_DMA_ENABLE_IT(hdma, (DMA_IT_TC | DMA_IT_TE));
|
||||
}
|
||||
/* Enable the Peripheral */
|
||||
__HAL_DMA_ENABLE(hdma);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
/* Remain BUSY */
|
||||
status = HAL_BUSY;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort the DMA Transfer.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if(hdma->State != HAL_DMA_STATE_BUSY)
|
||||
{
|
||||
/* no transfer ongoing */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable DMA IT */
|
||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||
|
||||
/* Disable the channel */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||
}
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aborts the DMA Transfer in Interrupt mode.
|
||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if(HAL_DMA_STATE_BUSY != hdma->State)
|
||||
{
|
||||
/* no transfer ongoing */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable DMA IT */
|
||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||
|
||||
/* Disable the channel */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Clear all flags */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_GI_FLAG_INDEX(hdma));
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
/* Call User Abort callback */
|
||||
if(hdma->XferAbortCallback != NULL)
|
||||
{
|
||||
hdma->XferAbortCallback(hdma);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polling for transfer complete.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param CompleteLevel: Specifies the DMA level complete.
|
||||
* @param Timeout: Timeout duration.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
if(HAL_DMA_STATE_BUSY != hdma->State)
|
||||
{
|
||||
/* no transfer ongoing */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
|
||||
__HAL_UNLOCK(hdma);
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Polling mode not supported in circular mode */
|
||||
if (RESET != (hdma->Instance->CCR & DMA_CCR_CIRC))
|
||||
{
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Get the level transfer complete flag */
|
||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
||||
{
|
||||
/* Transfer Complete flag */
|
||||
temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Half Transfer Complete flag */
|
||||
temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
|
||||
}
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
|
||||
{
|
||||
if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
|
||||
{
|
||||
/* When a DMA transfer error occurs */
|
||||
/* A hardware clear of its EN bits is performed */
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State= HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Check for the Timeout */
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
|
||||
{
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
||||
{
|
||||
/* Clear the transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||
|
||||
/* The selected Channelx EN bit is cleared (DMA is disabled and
|
||||
all transfers are complete) */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the half transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles DMA interrupt request.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t flag_it = hdma->DmaBaseAddress->ISR;
|
||||
uint32_t source_it = hdma->Instance->CCR;
|
||||
|
||||
/* Half Transfer Complete Interrupt management ******************************/
|
||||
if (((flag_it & (DMA_FLAG_HT1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_HT) != RESET))
|
||||
{
|
||||
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
|
||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
/* Disable the half transfer interrupt */
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
||||
}
|
||||
/* Clear the half transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||
|
||||
/* DMA peripheral state is not updated in Half Transfer */
|
||||
/* but in Transfer Complete case */
|
||||
|
||||
if(hdma->XferHalfCpltCallback != NULL)
|
||||
{
|
||||
/* Half transfer callback */
|
||||
hdma->XferHalfCpltCallback(hdma);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer Complete Interrupt management ***********************************/
|
||||
else if (((flag_it & (DMA_FLAG_TC1 << hdma->ChannelIndex)) != RESET) && ((source_it & DMA_IT_TC) != RESET))
|
||||
{
|
||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
/* Disable the transfer complete and error interrupt */
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
}
|
||||
/* Clear the transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
if(hdma->XferCpltCallback != NULL)
|
||||
{
|
||||
/* Transfer complete callback */
|
||||
hdma->XferCpltCallback(hdma);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer Error Interrupt management **************************************/
|
||||
else if (( RESET != (flag_it & (DMA_FLAG_TE1 << hdma->ChannelIndex))) && (RESET != (source_it & DMA_IT_TE)))
|
||||
{
|
||||
/* When a DMA transfer error occurs */
|
||||
/* A hardware clear of its EN bits is performed */
|
||||
/* Disable ALL DMA IT */
|
||||
__HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
|
||||
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||
|
||||
/* Update error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_TE;
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
if (hdma->XferErrorCallback != NULL)
|
||||
{
|
||||
/* Transfer error callback */
|
||||
hdma->XferErrorCallback(hdma);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register callbacks
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param CallbackID: User Callback identifer
|
||||
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
||||
* @param pCallback: pointer to private callbacsk function which has pointer to
|
||||
* a DMA_HandleTypeDef structure as parameter.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)( DMA_HandleTypeDef * _hdma))
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
if(HAL_DMA_STATE_READY == hdma->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||
hdma->XferCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||
hdma->XferHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_ERROR_CB_ID:
|
||||
hdma->XferErrorCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_ABORT_CB_ID:
|
||||
hdma->XferAbortCallback = pCallback;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UnRegister callbacks
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param CallbackID: User Callback identifer
|
||||
* a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
if(HAL_DMA_STATE_READY == hdma->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_DMA_XFER_CPLT_CB_ID:
|
||||
hdma->XferCpltCallback = NULL;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_HALFCPLT_CB_ID:
|
||||
hdma->XferHalfCpltCallback = NULL;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_ERROR_CB_ID:
|
||||
hdma->XferErrorCallback = NULL;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_ABORT_CB_ID:
|
||||
hdma->XferAbortCallback = NULL;
|
||||
break;
|
||||
|
||||
case HAL_DMA_XFER_ALL_CB_ID:
|
||||
hdma->XferCpltCallback = NULL;
|
||||
hdma->XferHalfCpltCallback = NULL;
|
||||
hdma->XferErrorCallback = NULL;
|
||||
hdma->XferAbortCallback = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief the DMA channel map.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param MapReqNum: request number
|
||||
* This parameter can be a value of @ref DMA_Channel_map
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMA_ChannelMap(DMA_HandleTypeDef *hdma, uint32_t MapReqNum)
|
||||
{
|
||||
uint32_t position; //Calculate channel number
|
||||
|
||||
assert_param(IS_DMA_MAP_VALUE(MapReqNum));
|
||||
|
||||
position = ((uint32_t)hdma->Instance - (uint32_t)DMA1_Channel1) / ((uint32_t)DMA1_Channel2 - (uint32_t)DMA1_Channel1);
|
||||
|
||||
/* Enable SYSCFG Clock */
|
||||
__HAL_RCC_SYSCFG_CLK_ENABLE();
|
||||
|
||||
MODIFY_REG(SYSCFG->CFGR3, (0x1F << (8U * (position & 0x03U))), (MapReqNum << (8U * (position & 0x03U))));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group3 Peripheral State and Errors functions
|
||||
* @brief Peripheral State and Errors functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State and Errors functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Check the DMA state
|
||||
(+) Get error code
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the DMA hande state.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Return DMA handle state */
|
||||
return hdma->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the DMA error code.
|
||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval DMA Error Code
|
||||
*/
|
||||
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
return hdma->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets the DMA Transfer parameter.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
/* Clear all flags */
|
||||
hdma->DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << hdma->ChannelIndex);
|
||||
|
||||
/* Configure DMA Channel data length */
|
||||
hdma->Instance->CNDTR = DataLength;
|
||||
|
||||
/* Memory to Peripheral */
|
||||
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
|
||||
{
|
||||
/* Configure DMA Channel destination address */
|
||||
hdma->Instance->CPAR = DstAddress;
|
||||
|
||||
/* Configure DMA Channel source address */
|
||||
hdma->Instance->CMAR = SrcAddress;
|
||||
}
|
||||
/* Peripheral to Memory */
|
||||
else
|
||||
{
|
||||
/* Configure DMA Channel source address */
|
||||
hdma->Instance->CPAR = SrcAddress;
|
||||
|
||||
/* Configure DMA Channel destination address */
|
||||
hdma->Instance->CMAR = DstAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
565
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_exti.c
Normal file
565
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_exti.c
Normal file
@@ -0,0 +1,565 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_exti.c
|
||||
* @author MCU Application Team
|
||||
* @brief EXTI HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the General Purpose Input/Output (EXTI) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### EXTI Peripheral features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) Each Exti line can be configured within this driver.
|
||||
|
||||
(+) Exti line can be configured in 3 different modes
|
||||
(++) Interrupt
|
||||
(++) Event
|
||||
(++) Both of them
|
||||
|
||||
(+) Configurable Exti lines can be configured with 3 different triggers
|
||||
(++) Rising
|
||||
(++) Falling
|
||||
(++) Both of them
|
||||
|
||||
(+) When set in interrupt mode, configurable Exti lines have two diffenrents
|
||||
interrupt pending registers which allow to distinguish which transition
|
||||
occurs:
|
||||
(++) Rising edge pending interrupt
|
||||
(++) Falling
|
||||
|
||||
(+) Exti lines 0 to 15 are linked to gpio pin number 0 to 15. Gpio port can
|
||||
be selected throught multiplexer.
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
|
||||
(#) Configure the EXTI line using HAL_EXTI_SetConfigLine().
|
||||
(++) Choose the interrupt line number by setting "Line" member from
|
||||
EXTI_ConfigTypeDef structure.
|
||||
(++) Configure the interrupt and/or event mode using "Mode" member from
|
||||
EXTI_ConfigTypeDef structure.
|
||||
(++) For configurable lines, configure rising and/or falling trigger
|
||||
"Trigger" member from EXTI_ConfigTypeDef structure.
|
||||
(++) For Exti lines linked to gpio, choose gpio port using "GPIOSel"
|
||||
member from GPIO_InitTypeDef structure.
|
||||
|
||||
(#) Get current Exti configuration of a dedicated line using
|
||||
HAL_EXTI_GetConfigLine().
|
||||
(++) Provide exiting handle as parameter.
|
||||
(++) Provide pointer on EXTI_ConfigTypeDef structure as second parameter.
|
||||
|
||||
(#) Clear Exti configuration of a dedicated line using HAL_EXTI_GetConfigLine().
|
||||
(++) Provide exiting handle as parameter.
|
||||
|
||||
(#) Register callback to treat Exti interrupts using HAL_EXTI_RegisterCallback().
|
||||
(++) Provide exiting handle as first parameter.
|
||||
(++) Provide which callback will be registered using one value from
|
||||
EXTI_CallbackIDTypeDef.
|
||||
(++) Provide callback function pointer.
|
||||
|
||||
(#) Get interrupt pending bit using HAL_EXTI_GetPending().
|
||||
|
||||
(#) Clear interrupt pending bit using HAL_EXTI_GetPending().
|
||||
|
||||
(#) Generate software interrupt using HAL_EXTI_GenerateSWI().
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rule:
|
||||
* Rule-18.1_b - Medium: Array `EXTICR' 1st subscript interval [0,7] may be out
|
||||
* of bounds [0,3] in following API :
|
||||
* HAL_EXTI_SetConfigLine
|
||||
* HAL_EXTI_GetConfigLine
|
||||
* HAL_EXTI_ClearConfigLine
|
||||
*/
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines ------------------------------------------------------------*/
|
||||
/** @defgroup EXTI_Private_Constants EXTI Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define EXTI_MODE_OFFSET 0x04u /* 0x10: offset between CPU IMR/EMR registers */
|
||||
#define EXTI_CONFIG_OFFSET 0x08u /* 0x20: offset between CPU Rising/Falling configuration registers */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions_Group1
|
||||
* @brief Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Configuration functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param pExtiConfig Pointer on EXTI configuration to be set.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check null pointer */
|
||||
if ((hexti == NULL) || (pExtiConfig == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(pExtiConfig->Line));
|
||||
assert_param(IS_EXTI_MODE(pExtiConfig->Mode));
|
||||
|
||||
/* Assign line number to handle */
|
||||
hexti->Line = pExtiConfig->Line;
|
||||
|
||||
/* Compute line mask */
|
||||
linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* Configure triggers for configurable lines */
|
||||
if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
assert_param(IS_EXTI_TRIGGER(pExtiConfig->Trigger));
|
||||
|
||||
/* Configure rising trigger */
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_RISING) != 0x00u)
|
||||
{
|
||||
EXTI->RTSR |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXTI->RTSR &= ~maskline;
|
||||
}
|
||||
|
||||
/* Configure falling trigger */
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Trigger & EXTI_TRIGGER_FALLING) != 0x00u)
|
||||
{
|
||||
EXTI->FTSR |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXTI->FTSR &= ~maskline;
|
||||
}
|
||||
|
||||
|
||||
/* Configure gpio port selection in case of gpio exti line */
|
||||
if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PORT(pExtiConfig->GPIOSel));
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = EXTI->EXTICR[linepos >> 2u];
|
||||
regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
regval |= (pExtiConfig->GPIOSel << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
EXTI->EXTICR[linepos >> 2u] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure interrupt mode : read current mode */
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_INTERRUPT) != 0x00u)
|
||||
{
|
||||
EXTI->IMR |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXTI->IMR &= ~maskline;
|
||||
}
|
||||
|
||||
/* Configure event mode : read current mode */
|
||||
/* Mask or set line */
|
||||
if ((pExtiConfig->Mode & EXTI_MODE_EVENT) != 0x00u)
|
||||
{
|
||||
EXTI->EMR |= maskline;
|
||||
}
|
||||
else
|
||||
{
|
||||
EXTI->EMR &= ~maskline;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param pExtiConfig Pointer on structure to store Exti configuration.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check null pointer */
|
||||
if ((hexti == NULL) || (pExtiConfig == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
|
||||
/* Store handle line number to configuration structure */
|
||||
pExtiConfig->Line = hexti->Line;
|
||||
|
||||
/* Compute line mask */
|
||||
linepos = (pExtiConfig->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* 1] Get core mode : interrupt */
|
||||
|
||||
/* Check if selected line is enable */
|
||||
if ((EXTI->IMR & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_INTERRUPT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtiConfig->Mode = EXTI_MODE_NONE;
|
||||
}
|
||||
|
||||
/* Get event mode */
|
||||
/* Check if selected line is enable */
|
||||
if ((EXTI->EMR & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Mode |= EXTI_MODE_EVENT;
|
||||
}
|
||||
|
||||
/* 2] Get trigger for configurable lines : rising */
|
||||
if ((pExtiConfig->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((EXTI->RTSR & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_RISING;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
|
||||
}
|
||||
|
||||
/* Get falling configuration */
|
||||
/* Check if configuration of selected line is enable */
|
||||
if ((EXTI->FTSR & maskline) != 0x00u)
|
||||
{
|
||||
pExtiConfig->Trigger |= EXTI_TRIGGER_FALLING;
|
||||
}
|
||||
|
||||
/* Get Gpio port selection for gpio lines */
|
||||
if ((pExtiConfig->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = EXTI->EXTICR[linepos >> 2u];
|
||||
pExtiConfig->GPIOSel = ((regval << (EXTI_EXTICR1_EXTI1_Pos * (3uL - (linepos & 0x03u)))) >> 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtiConfig->GPIOSel = 0x00u;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No Trigger selected */
|
||||
pExtiConfig->Trigger = EXTI_TRIGGER_NONE;
|
||||
pExtiConfig->GPIOSel = 0x00u;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear whole configuration of a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check null pointer */
|
||||
if (hexti == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
|
||||
/* compute line mask */
|
||||
linepos = (hexti->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* 1] Clear interrupt mode */
|
||||
EXTI->IMR = (EXTI->IMR & ~maskline);
|
||||
|
||||
/* 2] Clear event mode */
|
||||
EXTI->EMR = (EXTI->EMR & ~maskline);
|
||||
|
||||
/* 3] Clear triggers in case of configurable lines */
|
||||
if ((hexti->Line & EXTI_CONFIG) != 0x00u)
|
||||
{
|
||||
EXTI->RTSR = (EXTI->RTSR & ~maskline);
|
||||
EXTI->FTSR = (EXTI->FTSR & ~maskline);
|
||||
|
||||
/* Get Gpio port selection for gpio lines */
|
||||
if ((hexti->Line & EXTI_GPIO) == EXTI_GPIO)
|
||||
{
|
||||
assert_param(IS_EXTI_GPIO_PIN(linepos));
|
||||
|
||||
regval = EXTI->EXTICR[linepos >> 2u];
|
||||
regval &= ~(EXTI_EXTICR1_EXTI0 << (EXTI_EXTICR1_EXTI1_Pos * (linepos & 0x03u)));
|
||||
EXTI->EXTICR[linepos >> 2u] = regval;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register callback for a dedicated Exti line.
|
||||
* @param hexti Exti handle.
|
||||
* @param CallbackID User callback identifier.
|
||||
* This parameter can be one of @arg @ref EXTI_CallbackIDTypeDef values.
|
||||
* @param pPendingCbfn function pointer to be stored as callback.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_EXTI_COMMON_CB_ID:
|
||||
hexti->PendingCallback = pPendingCbfn;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store line number as handle private field.
|
||||
* @param hexti Exti handle.
|
||||
* @param ExtiLine Exti line number.
|
||||
* This parameter can be from 0 to @ref EXTI_LINE_NB.
|
||||
* @retval HAL Status.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_EXTI_LINE(ExtiLine));
|
||||
|
||||
/* Check null pointer */
|
||||
if (hexti == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Store line number as handle private field */
|
||||
hexti->Line = ExtiLine;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_Exported_Functions_Group2
|
||||
* @brief EXTI IO functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle EXTI interrupt request.
|
||||
* @param hexti Exti handle.
|
||||
* @retval none.
|
||||
*/
|
||||
void HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t maskline;
|
||||
|
||||
/* Compute line mask */
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
/* Get pending bit */
|
||||
regval = (EXTI->PR & maskline);
|
||||
if (regval != 0x00u)
|
||||
{
|
||||
/* Clear pending bit */
|
||||
EXTI->PR = maskline;
|
||||
|
||||
/* Call callback */
|
||||
if (hexti->PendingCallback != NULL)
|
||||
{
|
||||
hexti->PendingCallback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get interrupt pending bit of a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @param Edge Specify which pending edge as to be checked.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref EXTI_TRIGGER_RISING_FALLING
|
||||
* This parameter is kept for compatibility with other series.
|
||||
* @retval 1 if interrupt is pending else 0.
|
||||
*/
|
||||
uint32_t HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t linepos;
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_PENDING_EDGE(Edge));
|
||||
|
||||
/* Compute line mask */
|
||||
linepos = (hexti->Line & EXTI_PIN_MASK);
|
||||
maskline = (1uL << linepos);
|
||||
|
||||
/* return 1 if bit is set else 0 */
|
||||
regval = ((EXTI->PR & maskline) >> linepos);
|
||||
return regval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt pending bit of a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @param Edge Specify which pending edge as to be clear.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref EXTI_TRIGGER_RISING_FALLING
|
||||
* This parameter is kept for compatibility with other series.
|
||||
* @retval None.
|
||||
*/
|
||||
void HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
|
||||
/* Compute line mask */
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
/* Clear Pending bit */
|
||||
EXTI->PR = maskline;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Generate a software interrupt for a dedicated line.
|
||||
* @param hexti Exti handle.
|
||||
* @retval None.
|
||||
*/
|
||||
void HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
|
||||
{
|
||||
uint32_t maskline;
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_EXTI_LINE(hexti->Line));
|
||||
assert_param(IS_EXTI_CONFIG_LINE(hexti->Line));
|
||||
|
||||
/* Compute line mask */
|
||||
maskline = (1uL << (hexti->Line & EXTI_PIN_MASK));
|
||||
|
||||
/* Generate Software interrupt */
|
||||
EXTI->SWIER = maskline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
1014
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_flash.c
Normal file
1014
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_flash.c
Normal file
@@ -0,0 +1,1014 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_flash.c
|
||||
* @author MCU Application Team
|
||||
* @brief FLASH HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the internal FLASH memory:
|
||||
* + Program operations functions
|
||||
* + Memory Control functions
|
||||
* + Peripheral Errors functions
|
||||
*
|
||||
@verbatim
|
||||
|
||||
******************************************************************************
|
||||
* @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"
|
||||
|
||||
/** @defgroup FLASH FLASH
|
||||
* @brief FLASH HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Variables FLASH Private Variables
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Variable used for Program/Erase sectors under interruption
|
||||
*/
|
||||
FLASH_ProcessTypeDef pFlash = {.Lock = HAL_UNLOCKED, \
|
||||
.ErrorCode = HAL_FLASH_ERROR_NONE, \
|
||||
.ProcedureOnGoing = FLASH_TYPENONE, \
|
||||
.Address = 0U, \
|
||||
.PageOrSector = 0U, \
|
||||
.NbPagesSectorsToErase = 0U
|
||||
};
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
const uint32_t _FlashTimmingParam[8] = {0x1FFF0F1C, 0x1FFF0F30, 0x1FFF0F44, 0x1FFF0F58, 0x1FFF0F6C, 0x1FFF0F1C, 0x1FFF0F1C, 0x1FFF0F1C};
|
||||
|
||||
/**
|
||||
* @brief Option byte program.
|
||||
* @note Enable this configuration, you need to add the corresponding optionbyte FLM file
|
||||
*/
|
||||
#ifdef FLASH_OPT_PROGRAM_ENABLED
|
||||
#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */
|
||||
const uint32_t u32ICG[] __attribute__((section(".opt_sec"))) =
|
||||
#elif defined (__CC_ARM)
|
||||
const uint32_t u32ICG[] __attribute__((at(OB_BASE))) =
|
||||
#elif defined (__ICCARM__)
|
||||
__root const uint32_t u32ICG[] @ OB_BASE =
|
||||
#else
|
||||
#error "unsupported compiler!!"
|
||||
#endif
|
||||
{
|
||||
FLASH_OPTR_CONSTANT,
|
||||
FLASH_SDKR_CONSTANT,
|
||||
0xFFFFFFFF,
|
||||
FLASH_WRPR_CONSTANT,
|
||||
};
|
||||
#endif /* FLASH_OPT_PROGRAM_ENABLED */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Functions FLASH Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void FLASH_MassErase(void);
|
||||
static void FLASH_Program_Page(uint32_t Address, uint32_t * DataAddress);
|
||||
static void FLASH_PageErase(uint32_t PageAddress);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH control register access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
|
||||
{
|
||||
/* Authorize the FLASH Registers access */
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
|
||||
|
||||
/* verify Flash is unlock */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00U)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the FLASH control register access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Lock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Set the LOCK Bit to lock the FLASH Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
|
||||
|
||||
/* verify Flash is locked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0x00u)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH Option Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00U)
|
||||
{
|
||||
/* Authorizes the Option Byte register programming */
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
|
||||
|
||||
/* verify option bytes are unlocked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) == 0x00U)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the FLASH Option Bytes Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Set the OPTLOCK Bit to lock the FLASH Option Byte Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
|
||||
|
||||
/* verify option bytes are locked */
|
||||
if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK) != 0x00u)
|
||||
{
|
||||
status = HAL_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Launch the option byte loading.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
|
||||
{
|
||||
/* Set the bit to force the option byte reloading */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
|
||||
|
||||
/* We should not reach here : Option byte launch generates Option byte reset
|
||||
so return error */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the specific FLASH error flag.
|
||||
* @retval FLASH_ErrorCode The returned value can be
|
||||
* @arg @ref HAL_FLASH_ERROR_NONE No error set
|
||||
* @arg @ref HAL_FLASH_ERROR_WRP FLASH Write protection error
|
||||
* @arg @ref HAL_FLASH_ERROR_OPTV FLASH Option validity error
|
||||
* @note (*) availability depends on devices
|
||||
*/
|
||||
uint32_t HAL_FLASH_GetError(void)
|
||||
{
|
||||
return pFlash.ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wait for a FLASH operation to complete.
|
||||
* @param Timeout maximum flash operation timeout
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef FLASH_WaitForLastOperation(uint32_t Timeout)
|
||||
{
|
||||
/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
|
||||
Even if the FLASH operation fails, the BUSY flag will be reset and an error
|
||||
flag will be set */
|
||||
uint32_t timeout = HAL_GetTick() + Timeout;
|
||||
|
||||
/* Wait if any operation is ongoing */
|
||||
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0x00U)
|
||||
{
|
||||
if (HAL_GetTick() >= timeout)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear SR register */
|
||||
FLASH->SR = FLASH_FLAG_SR_CLEAR;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full erase of FLASH memory Bank
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_MassErase(void)
|
||||
{
|
||||
/* Clean the error context */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
/* Only bank1 will be erased*/
|
||||
SET_BIT(FLASH->CR, FLASH_CR_MER);
|
||||
*(__IO uint32_t *)(0x08000000) = 0x12344321;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Page erase of FLASH memory
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_PageErase(uint32_t PageAddress)
|
||||
{
|
||||
/* Clean the error context */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PER);
|
||||
*(__IO uint32_t *)(PageAddress) = 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sector erase of FLASH memory
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_SectorErase(uint32_t SectorAddress)
|
||||
{
|
||||
SET_BIT(FLASH->CR, FLASH_CR_SER);
|
||||
*(__IO uint32_t *)(SectorAddress) = 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Page program of FLASH memory
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
static __RAM_FUNC void FLASH_Program_Page(uint32_t Address, uint32_t * DataAddress)
|
||||
{
|
||||
|
||||
uint8_t index=0;
|
||||
uint32_t dest = Address;
|
||||
uint32_t * src = DataAddress;
|
||||
uint32_t primask_bit;
|
||||
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
/* Enter critical section */
|
||||
primask_bit = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
/* 32 words*/
|
||||
while(index<32U)
|
||||
{
|
||||
*(uint32_t *)dest = *src;
|
||||
src += 1U;
|
||||
dest += 4U;
|
||||
index++;
|
||||
if(index==31)
|
||||
{
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PGSTRT);
|
||||
}
|
||||
}
|
||||
|
||||
/* Exit critical section: restore previous priority mask */
|
||||
__set_PRIMASK(primask_bit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform a mass erase or erase the specified FLASH memory pages
|
||||
* @note To correctly run this function, the @ref HAL_FLASH_Unlock() function
|
||||
* must be called before.
|
||||
* Call the @ref HAL_FLASH_Lock() to disable the flash memory access
|
||||
* (recommended to protect the FLASH memory against possible unwanted operation)
|
||||
* @param[in] pEraseInit pointer to an FLASH_EraseInitTypeDef structure that
|
||||
* contains the configuration information for the erasing.
|
||||
*
|
||||
* @param[out] PageSectorError pointer to variable that
|
||||
* contains the configuration information on faulty page or sector in case of error
|
||||
* (0xFFFFFFFF means that all the pages or sectors have been correctly erased)
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Erase(FLASH_EraseInitTypeDef *pEraseInit, uint32_t *PageSectorError)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
uint32_t address = 0U;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Config flash timming */
|
||||
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
||||
{
|
||||
/* Mass Erase requested for Bank1 */
|
||||
/* Wait for last operation to be completed */
|
||||
if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
|
||||
{
|
||||
/*Mass erase to be done*/
|
||||
FLASH_MassErase();
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the erase operation is completed, disable the MER Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
|
||||
}
|
||||
}else if(pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
|
||||
{
|
||||
/* Page Erase is requested */
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->PageAddress));
|
||||
assert_param(IS_FLASH_NB_PAGES(pEraseInit->PageAddress, pEraseInit->NbPages));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
|
||||
{
|
||||
/*Initialization of PageSectorError variable*/
|
||||
*PageSectorError = 0xFFFFFFFFU;
|
||||
|
||||
/* Erase page by page to be done*/
|
||||
for(address = pEraseInit->PageAddress;
|
||||
address < ((pEraseInit->NbPages * FLASH_PAGE_SIZE) + pEraseInit->PageAddress);
|
||||
address += FLASH_PAGE_SIZE)
|
||||
{
|
||||
FLASH_PageErase(address);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
/* If the erase operation is completed, disable the PER Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* In case of error, stop erase procedure and return the faulty address */
|
||||
*PageSectorError = address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
|
||||
{
|
||||
/* Sector Erase is requested */
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(pEraseInit->SectorAddress));
|
||||
assert_param(IS_FLASH_NB_SECTORS(pEraseInit->SectorAddress, pEraseInit->NbSectors));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
if (FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE) == HAL_OK)
|
||||
{
|
||||
/*Initialization of PageSectorError variable*/
|
||||
*PageSectorError = 0xFFFFFFFFU;
|
||||
|
||||
/* Erase page by page to be done*/
|
||||
for(address = pEraseInit->SectorAddress;
|
||||
address < ((pEraseInit->NbSectors * FLASH_SECTOR_SIZE) + pEraseInit->SectorAddress);
|
||||
address += FLASH_SECTOR_SIZE)
|
||||
{
|
||||
FLASH_SectorErase(address);
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
/* If the erase operation is completed, disable the SER Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_SER);
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* In case of error, stop erase procedure and return the faulty address */
|
||||
*PageSectorError = address;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Perform a mass erase or erase the specified FLASH memory pages with interrupt enabled.
|
||||
* @param pEraseInit Pointer to an @ref FLASH_EraseInitTypeDef structure that
|
||||
* contains the configuration information for the erasing.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Erase_IT(FLASH_EraseInitTypeDef *pEraseInit)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEERASE(pEraseInit->TypeErase));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Config flash timming */
|
||||
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* save procedure for interrupt treatment */
|
||||
pFlash.ProcedureOnGoing = pEraseInit->TypeErase;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable End of Operation and Error interrupts */
|
||||
FLASH->CR |= FLASH_CR_EOPIE | FLASH_CR_ERRIE;
|
||||
|
||||
if (pEraseInit->TypeErase == FLASH_TYPEERASE_MASSERASE)
|
||||
{
|
||||
/* Set Page to 0 for Interrupt callback management */
|
||||
pFlash.PageOrSector = 0;
|
||||
|
||||
/* Proceed to Mass Erase */
|
||||
FLASH_MassErase();
|
||||
}else if (pEraseInit->TypeErase == FLASH_TYPEERASE_PAGEERASE)
|
||||
{
|
||||
/* Erase by page to be done */
|
||||
pFlash.NbPagesSectorsToErase = pEraseInit->NbPages;
|
||||
pFlash.PageOrSector = pEraseInit->PageAddress;
|
||||
|
||||
/*Erase 1st page and wait for IT */
|
||||
FLASH_PageErase(pEraseInit->PageAddress);
|
||||
}else if (pEraseInit->TypeErase == FLASH_TYPEERASE_SECTORERASE)
|
||||
{
|
||||
/* Erase by sector to be done */
|
||||
pFlash.NbPagesSectorsToErase = pEraseInit->NbSectors;
|
||||
pFlash.PageOrSector = pEraseInit->SectorAddress;
|
||||
|
||||
FLASH_SectorErase(pEraseInit->SectorAddress);
|
||||
}
|
||||
}
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program of a page at a specified address.
|
||||
* @param Address Specifies the address to be programmed.
|
||||
* @param DataAddr:Page Start Address
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_PageProgram(uint32_t Address, uint32_t * DataAddr )
|
||||
{
|
||||
return HAL_FLASH_Program(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program of a page at a specified address.
|
||||
* @param TypeProgram Indicate the way to program at a specified address.
|
||||
* This parameter can be a value of @ref FLASH_Type_Program
|
||||
* @param Address Specifies the address to be programmed.
|
||||
* @param DataAddr:Page Start Address
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint32_t * DataAddr )
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Config flash timming */
|
||||
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* must be the first address of the PAGE */
|
||||
if(Address%FLASH_PAGE_SIZE)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
FLASH_Program_Page(Address, DataAddr);
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
/* If the program operation is completed, disable the PG Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
/* In case of error, stop programming procedure */
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program of a page at a specified address with interrupt enabled.
|
||||
* @param Address Specifies the address to be programmed.
|
||||
* @param DataAddr Specifies the buffer address to be programmed.
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_PageProgram_IT(uint32_t Address, uint32_t *DataAddr)
|
||||
{
|
||||
return HAL_FLASH_Program_IT(FLASH_TYPEPROGRAM_PAGE, Address, DataAddr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program of a page at a specified address with interrupt enabled.
|
||||
* @param TypeProgram Indicate the way to program at a specified address.
|
||||
* This parameter can be a value of @ref FLASH_Type_Program
|
||||
* @param Address Specifies the address to be programmed.
|
||||
* @param DataAddr Specifies the buffer address to be programmed.
|
||||
*
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint32_t *DataAddr)
|
||||
{
|
||||
HAL_StatusTypeDef status;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Config flash timming */
|
||||
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
|
||||
|
||||
/* Reset error code */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation(FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}else
|
||||
{
|
||||
/* Set internal variables used by the IRQ handler */
|
||||
pFlash.ProcedureOnGoing = TypeProgram;
|
||||
pFlash.Address = Address;
|
||||
|
||||
/* Enable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
FLASH_Program_Page(Address, DataAddr);
|
||||
}
|
||||
|
||||
/* return status */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the read protection level.
|
||||
* @param ReadProtectLevel specifies the read protection level.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref OB_RDP_LEVEL_0 No protection
|
||||
* @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
|
||||
*
|
||||
* @note Warning: When enabling OB_RDP level 2 it's no more possible to go back to level 1 or 0
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_RDP_LevelConfig(uint8_t ReadProtectLevel)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_RDP_LEVEL(ReadProtectLevel));
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Clean the error context */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
/* If the previous operation is completed, proceed to erase the option bytes */
|
||||
SET_BIT(FLASH->OPTR, ReadProtectLevel);
|
||||
|
||||
/* starts to modify Flash Option bytes */
|
||||
FLASH->CR|=FLASH_CR_OPTSTRT;
|
||||
|
||||
/* set bit EOPIE */
|
||||
FLASH->CR|=FLASH_CR_EOPIE;
|
||||
|
||||
/* trigger program */
|
||||
*((__IO uint32_t *)(0x40022080))=0xff;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH User Option Byte value.
|
||||
* @retval The FLASH User Option Bytes values. It will be a combination of all the following values:
|
||||
* @arg @ref FLASH_OB_USER_BOR_ENABLE
|
||||
* @arg @ref FLASH_OB_USER_BOR_LEVEL
|
||||
* @arg @ref FLASH_OB_USER_RESET_CONFIG
|
||||
* @arg @ref FLASH_OB_USER_IWDG_SW
|
||||
* @arg @ref FLASH_OB_USER_WWDG_SW
|
||||
* @arg @ref FLASH_OB_USER_nBOOT1
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetUser(void)
|
||||
{
|
||||
uint32_t user = ((FLASH->OPTR & ~FLASH_OPTR_RDP) & OB_USER_ALL);
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the FLASH Read Protection level.
|
||||
* @retval FLASH ReadOut Protection Status:
|
||||
* This return value can be one of the following values:
|
||||
* @arg @ref OB_RDP_LEVEL_0 No protection
|
||||
* @arg @ref OB_RDP_LEVEL_1 Read protection of the memory
|
||||
*/
|
||||
static uint32_t FLASH_OB_GetRDP(void)
|
||||
{
|
||||
uint32_t rdplvl = READ_BIT(FLASH->OPTR, FLASH_OPTR_RDP);
|
||||
|
||||
if (rdplvl == OB_RDP_LEVEL_0)
|
||||
{
|
||||
return (OB_RDP_LEVEL_0);
|
||||
}else
|
||||
{
|
||||
return rdplvl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set user & RDP configuration
|
||||
* @param UserType The FLASH User Option Bytes to be modified.
|
||||
* This parameter can be a combination of @ref FLASH_OB_USER_Type
|
||||
* @param UserConfig The FLASH User Option Bytes values.
|
||||
* This parameter can be a combination of:
|
||||
* @arg @ref FLASH_OB_USER_BOR_ENABLE
|
||||
* @arg @ref FLASH_OB_USER_BOR_LEVEL
|
||||
* @arg @ref FLASH_OB_USER_RESET_CONFIG
|
||||
* @arg @ref FLASH_OB_USER_IWDG_SW
|
||||
* @arg @ref FLASH_OB_USER_WWDG_SW
|
||||
* @arg @ref FLASH_OB_USER_nBOOT1
|
||||
* @param RDPLevel specifies the read protection level.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref OB_RDP_LEVEL_0 No protection
|
||||
* @arg @ref OB_RDP_LEVEL_1 Memory Read protection
|
||||
* @note (*) availability depends on devices
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig, uint32_t RDPLevel)
|
||||
{
|
||||
uint32_t optr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OB_USER_TYPE(UserType));
|
||||
assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
|
||||
assert_param(IS_OB_RDP_LEVEL(RDPLevel));
|
||||
|
||||
/* Configure the RDP level in the option bytes register */
|
||||
optr = FLASH->OPTR;
|
||||
optr &= ~(UserType | FLASH_OPTR_RDP);
|
||||
FLASH->OPTR = (optr | UserConfig | RDPLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program option bytes
|
||||
* @note The function @ref HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
|
||||
* The function @ref HAL_FLASH_OB_Unlock() should be called before to unlock the options bytes
|
||||
* The function @ref HAL_FLASH_OB_Launch() should be called after to force the reload of the options bytes
|
||||
* (system reset will occur)
|
||||
*
|
||||
* @param pOBInit pointer to an FLASH_OBInitStruct structure that
|
||||
* contains the configuration information for the programming.
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OBProgram(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
uint32_t optr;
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Config flash timming */
|
||||
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_OPTIONBYTE(pOBInit->OptionType));
|
||||
|
||||
/* WRP register */
|
||||
if ((pOBInit->OptionType & OPTIONBYTE_WRP) != 0)
|
||||
{
|
||||
/* Write protection configuration */
|
||||
FLASH->WRPR = (uint16_t)(~(pOBInit->WRPSector));
|
||||
}
|
||||
|
||||
/* SDK register */
|
||||
if ((pOBInit->OptionType & OPTIONBYTE_SDK) != 0)
|
||||
{
|
||||
/* SDK protection configuration */
|
||||
FLASH->SDKR = (pOBInit->SDKStartAddr) | (pOBInit->SDKEndAddr<<8);
|
||||
}
|
||||
|
||||
/* Option register */
|
||||
if ((pOBInit->OptionType & (OPTIONBYTE_RDP | OPTIONBYTE_USER)) == (OPTIONBYTE_RDP | OPTIONBYTE_USER))
|
||||
{
|
||||
/* Fully modify OPTR register with RDP & user data */
|
||||
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, pOBInit->RDPLevel);
|
||||
}
|
||||
else if((pOBInit->OptionType & OPTIONBYTE_RDP) != 0x00U)
|
||||
{
|
||||
/* Only modify RDP so get current user data */
|
||||
optr = FLASH_OB_GetUser();
|
||||
FLASH_OB_OptrConfig(optr, optr, pOBInit->RDPLevel);
|
||||
}
|
||||
else if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
|
||||
{
|
||||
/* Only modify user so get current RDP level */
|
||||
optr = FLASH_OB_GetRDP();
|
||||
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig, optr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
/* starts to modify Flash Option bytes */
|
||||
FLASH->CR|=FLASH_CR_OPTSTRT;
|
||||
|
||||
/* set bit EOPIE */
|
||||
FLASH->CR|=FLASH_CR_EOPIE;
|
||||
|
||||
/* trigger program */
|
||||
*((__IO uint32_t *)(0x40022080))=0xff;
|
||||
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Option byte configuration
|
||||
* @param pOBInit pointer to an FLASH_OBInitStruct structure that
|
||||
* contains the configuration information for the programming.
|
||||
*
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASH_OBGetConfig(FLASH_OBProgramInitTypeDef *pOBInit)
|
||||
{
|
||||
pOBInit->OptionType = OPTIONBYTE_ALL;
|
||||
|
||||
/* Get WRP sector */
|
||||
pOBInit->WRPSector = (uint16_t)(~FLASH->WRPR);
|
||||
|
||||
/* Get SDK sector */
|
||||
pOBInit->SDKStartAddr = (FLASH->SDKR)&0x1F;
|
||||
pOBInit->SDKEndAddr = ((FLASH->SDKR)&0x1F00)>>8;
|
||||
|
||||
/*Get RDP Level*/
|
||||
if (((FLASH->OPTR)&0xFF) == OB_RDP_LEVEL_0)
|
||||
{
|
||||
pOBInit->RDPLevel = OB_RDP_LEVEL_0;
|
||||
} else
|
||||
{
|
||||
pOBInit->RDPLevel = OB_RDP_LEVEL_1;
|
||||
}
|
||||
|
||||
/*Get USER*/
|
||||
pOBInit->USERType = OB_USER_ALL;
|
||||
#if defined(FLASH_OPTR_WWDG_SW)
|
||||
pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_WWDG_SW | FLASH_OPTR_IWDG_SW | \
|
||||
FLASH_OPTR_NRST_MODE |FLASH_OPTR_BOR_EN | \
|
||||
FLASH_OPTR_BOR_LEV |FLASH_OPTR_nBOOT1);
|
||||
#else
|
||||
pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_IWDG_SW | \
|
||||
FLASH_OPTR_NRST_MODE |FLASH_OPTR_BOR_EN | \
|
||||
FLASH_OPTR_BOR_LEV |FLASH_OPTR_nBOOT1);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle FLASH interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASH_IRQHandler(void)
|
||||
{
|
||||
uint32_t param = 0xFFFFFFFFU;
|
||||
uint32_t error;
|
||||
|
||||
/* Save flash errors. Only ECC detection can be checked here as ECCC
|
||||
generates NMI */
|
||||
error = (FLASH->SR & FLASH_FLAG_SR_ERROR);
|
||||
|
||||
CLEAR_BIT(FLASH->CR, pFlash.ProcedureOnGoing);
|
||||
|
||||
/* A] Set parameter for user or error callbacks */
|
||||
/* check operation was a program or erase */
|
||||
if ((pFlash.ProcedureOnGoing & (FLASH_TYPEPROGRAM_PAGE)) != 0x00U)
|
||||
{
|
||||
/* return adress being programmed */
|
||||
param = pFlash.Address;
|
||||
}else if ((pFlash.ProcedureOnGoing & (FLASH_TYPEERASE_MASSERASE | FLASH_TYPEERASE_SECTORERASE | FLASH_TYPEERASE_PAGEERASE)) != 0x00U)
|
||||
{
|
||||
/* return page number being erased (0 for mass erase) */
|
||||
param = pFlash.PageOrSector;
|
||||
}else
|
||||
{
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
/* B] Check errors */
|
||||
if (error != 0x00U)
|
||||
{
|
||||
/*Save the error code*/
|
||||
pFlash.ErrorCode |= error;
|
||||
|
||||
/* clear error flags */
|
||||
__HAL_FLASH_CLEAR_FLAG(error);
|
||||
|
||||
/*Stop the procedure ongoing*/
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
|
||||
/* Error callback */
|
||||
HAL_FLASH_OperationErrorCallback(param);
|
||||
}
|
||||
|
||||
/* C] Check FLASH End of Operation flag */
|
||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP) != 0x00U)
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
||||
|
||||
if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_PAGEERASE)
|
||||
{
|
||||
/* Nb of pages to erased can be decreased */
|
||||
pFlash.NbPagesSectorsToErase--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if (pFlash.NbPagesSectorsToErase != 0x00U)
|
||||
{
|
||||
/* Increment page number */
|
||||
pFlash.PageOrSector += FLASH_PAGE_SIZE;
|
||||
FLASH_PageErase(pFlash.PageOrSector);
|
||||
}else
|
||||
{
|
||||
/* No more pages to erase: stop erase pages procedure */
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
}
|
||||
}
|
||||
else if (pFlash.ProcedureOnGoing == FLASH_TYPEERASE_SECTORERASE)
|
||||
{
|
||||
/* Nb of sectors to erased can be decreased */
|
||||
pFlash.NbPagesSectorsToErase--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if (pFlash.NbPagesSectorsToErase != 0x00U)
|
||||
{
|
||||
/* Increment page number */
|
||||
pFlash.PageOrSector += FLASH_SECTOR_SIZE;
|
||||
FLASH_SectorErase(pFlash.PageOrSector);
|
||||
}else
|
||||
{
|
||||
/* No more pages to erase: stop erase pages procedure */
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Stop the ongoing procedure */
|
||||
pFlash.ProcedureOnGoing = FLASH_TYPENONE;
|
||||
}
|
||||
|
||||
/* User callback */
|
||||
HAL_FLASH_EndOfOperationCallback(param);
|
||||
}
|
||||
|
||||
if (pFlash.ProcedureOnGoing == FLASH_TYPENONE)
|
||||
{
|
||||
/* Disable End of Operation and Error interrupts */
|
||||
__HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_OPERR);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FLASH end of operation interrupt callback.
|
||||
* @param ReturnValue The value saved in this parameter depends on the ongoing procedure
|
||||
* Mass Erase: 0
|
||||
* Page Erase: Page which has been erased
|
||||
* Program: Address which was selected for data program
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(ReturnValue);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_FLASH_EndOfOperationCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief FLASH operation error interrupt callback.
|
||||
* @param ReturnValue The value saved in this parameter depends on the ongoing procedure
|
||||
* Mass Erase: 0
|
||||
* Page Erase: Page number which returned an error
|
||||
* Program: Address which was selected for data program
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_FLASH_OperationErrorCallback(uint32_t ReturnValue)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(ReturnValue);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_FLASH_OperationErrorCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
532
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_gpio.c
Normal file
532
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_gpio.c
Normal file
@@ -0,0 +1,532 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_gpio.c
|
||||
* @author MCU Application Team
|
||||
* @brief GPIO HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the General Purpose Input/Output (GPIO) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### GPIO Peripheral features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
|
||||
configured by software in several modes:
|
||||
(++) Input mode
|
||||
(++) Analog mode
|
||||
(++) Output mode
|
||||
(++) Alternate function mode
|
||||
(++) External interrupt/event lines
|
||||
|
||||
(+) During and just after reset, the alternate functions and external interrupt
|
||||
lines are not active and the I/O ports are configured in input floating mode.
|
||||
|
||||
(+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
|
||||
activated or not.
|
||||
|
||||
(+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
|
||||
type and the IO speed can be selected depending on the VDD value.
|
||||
|
||||
(+) The microcontroller IO pins are connected to onboard peripherals/modules through a
|
||||
multiplexer that allows only one peripheral alternate function (AF) connected
|
||||
to an IO pin at a time. In this way, there can be no conflict between peripherals
|
||||
sharing the same IO pin.
|
||||
|
||||
(+) All ports have external interrupt/event capability. To use external interrupt
|
||||
lines, the port must be configured in input mode. All available GPIO pins are
|
||||
connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
|
||||
|
||||
(+) The external interrupt/event controller consists of up to 28 edge detectors
|
||||
(16 lines are connected to GPIO) for generating event/interrupt requests (each
|
||||
input line can be independently configured to select the type (interrupt or event)
|
||||
and the corresponding trigger event (rising or falling or both). Each line can
|
||||
also be masked independently.
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
|
||||
|
||||
(#) Configure the GPIO pin(s) using HAL_GPIO_Init().
|
||||
(++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
|
||||
(++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
|
||||
structure.
|
||||
(++) In case of Output or alternate function mode selection: the speed is
|
||||
configured through "Speed" member from GPIO_InitTypeDef structure.
|
||||
(++) In alternate mode is selection, the alternate function connected to the IO
|
||||
is configured through "Alternate" member from GPIO_InitTypeDef structure.
|
||||
(++) Analog mode is required when a pin is to be used as ADC channel
|
||||
or DAC output.
|
||||
(++) In case of external interrupt/event selection the "Mode" member from
|
||||
GPIO_InitTypeDef structure select the type (interrupt or event) and
|
||||
the corresponding trigger event (rising or falling or both).
|
||||
|
||||
(#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
|
||||
mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
|
||||
HAL_NVIC_EnableIRQ().
|
||||
|
||||
(#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
|
||||
|
||||
(#) To set/reset the level of a pin configured in output mode use
|
||||
HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
|
||||
|
||||
(#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
|
||||
|
||||
(#) During and just after reset, the alternate functions are not
|
||||
active and the GPIO pins are configured in input floating mode (except JTAG
|
||||
pins).
|
||||
|
||||
(#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
|
||||
when the LSE oscillator is off. The LSE has priority over the GPIO function.
|
||||
|
||||
(#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
|
||||
general purpose PF0 and PF1, respectively, when the HSE oscillator is off.
|
||||
The HSE has priority over the GPIO function.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
|
||||
*
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rules:
|
||||
* Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
|
||||
* range of the shift operator in following API :
|
||||
* HAL_GPIO_Init
|
||||
* HAL_GPIO_DeInit
|
||||
*/
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines ------------------------------------------------------------*/
|
||||
/** @defgroup GPIO_Private_Constants GPIO Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define GPIO_MODE (0x00000003u)
|
||||
#define EXTI_MODE (0x10000000u)
|
||||
#define GPIO_MODE_IT (0x00010000u)
|
||||
#define GPIO_MODE_EVT (0x00020000u)
|
||||
#define RISING_EDGE (0x00100000u)
|
||||
#define FALLING_EDGE (0x00200000u)
|
||||
#define GPIO_OUTPUT_TYPE (0x00000010u)
|
||||
|
||||
#define GPIO_NUMBER (16u)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define __GPIO_LOCK_KEY_Msk (0x00030000U)
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup GPIO_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Exported_Functions_Group1
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Init pointer to a GPIO_InitTypeDef structure that contains
|
||||
* the configuration information for the specified GPIO peripheral.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
||||
{
|
||||
uint32_t position = 0x00u;
|
||||
uint32_t iocurrent;
|
||||
uint32_t temp;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
|
||||
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
|
||||
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||
|
||||
/* Configure the port pins */
|
||||
while (((GPIO_Init->Pin) >> position) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Init->Pin) & (1uL << position);
|
||||
|
||||
if (iocurrent != 0x00u)
|
||||
{
|
||||
/*--------------------- GPIO Mode Configuration ------------------------*/
|
||||
/* In case of Alternate function mode selection */
|
||||
if ((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||
{
|
||||
/* Check the Alternate function parameters */
|
||||
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
|
||||
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
temp = GPIOx->AFR[position >> 3u];
|
||||
temp &= ~(0xFu << ((position & 0x07u) * 4u));
|
||||
temp |= ((GPIO_Init->Alternate) << ((position & 0x07u) * 4u));
|
||||
GPIOx->AFR[position >> 3u] = temp;
|
||||
}
|
||||
|
||||
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||
temp = GPIOx->MODER;
|
||||
temp &= ~(GPIO_MODER_MODE0 << (position * 2u));
|
||||
temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2u));
|
||||
GPIOx->MODER = temp;
|
||||
|
||||
/* In case of Output or Alternate function mode selection */
|
||||
if ((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
|
||||
(GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD))
|
||||
{
|
||||
/* Check the Speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
/* Configure the IO Speed */
|
||||
temp = GPIOx->OSPEEDR;
|
||||
temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
|
||||
temp |= (GPIO_Init->Speed << (position * 2u));
|
||||
GPIOx->OSPEEDR = temp;
|
||||
|
||||
/* Configure the IO Output Type */
|
||||
temp = GPIOx->OTYPER;
|
||||
temp &= ~(GPIO_OTYPER_OT0 << position) ;
|
||||
temp |= (((GPIO_Init->Mode & GPIO_OUTPUT_TYPE) >> 4u) << position);
|
||||
GPIOx->OTYPER = temp;
|
||||
}
|
||||
|
||||
/* Activate the Pull-up or Pull down resistor for the current IO */
|
||||
temp = GPIOx->PUPDR;
|
||||
temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
|
||||
temp |= ((GPIO_Init->Pull) << (position * 2u));
|
||||
GPIOx->PUPDR = temp;
|
||||
|
||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||
/* Configure the External Interrupt or event for the current IO */
|
||||
if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
||||
{
|
||||
temp = EXTI->EXTICR[position >> 2u];
|
||||
temp &= ~(0x0FuL << (8u * (position & 0x03u)));
|
||||
temp |= (GPIO_GET_INDEX(GPIOx) << (8u * (position & 0x03u)));
|
||||
EXTI->EXTICR[position >> 2u] = temp;
|
||||
|
||||
/* Clear EXTI line configuration */
|
||||
temp = EXTI->IMR;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->IMR = temp;
|
||||
|
||||
temp = EXTI->EMR;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->EMR = temp;
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
temp = EXTI->RTSR;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->RTSR = temp;
|
||||
|
||||
temp = EXTI->FTSR;
|
||||
temp &= ~(iocurrent);
|
||||
if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
||||
{
|
||||
temp |= iocurrent;
|
||||
}
|
||||
EXTI->FTSR = temp;
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize the GPIOx peripheral registers to their default reset values.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Pin specifies the port bit to be written.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_DeInit(GPIO_TypeDef *GPIOx, uint32_t GPIO_Pin)
|
||||
{
|
||||
uint32_t position = 0x00u;
|
||||
uint32_t iocurrent;
|
||||
uint32_t tmp;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
/* Configure the port pins */
|
||||
while ((GPIO_Pin >> position) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Pin) & (1uL << position);
|
||||
|
||||
if (iocurrent != 0x00u)
|
||||
{
|
||||
/*------------------------- EXTI Mode Configuration --------------------*/
|
||||
/* Clear the External Interrupt or Event for the current IO */
|
||||
|
||||
tmp = EXTI->EXTICR[position >> 2u];
|
||||
tmp &= (0x0FuL << (8u * (position & 0x03u)));
|
||||
if (tmp == (GPIO_GET_INDEX(GPIOx) << (8u * (position & 0x03u))))
|
||||
{
|
||||
/* Clear EXTI line configuration */
|
||||
EXTI->IMR &= ~(iocurrent);
|
||||
EXTI->EMR &= ~(iocurrent);
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
EXTI->RTSR &= ~(iocurrent);
|
||||
EXTI->FTSR &= ~(iocurrent);
|
||||
|
||||
tmp = 0x0FuL << (8u * (position & 0x03u));
|
||||
EXTI->EXTICR[position >> 2u] &= ~tmp;
|
||||
}
|
||||
|
||||
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||
/* Configure IO in Analog Mode */
|
||||
GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2u));
|
||||
|
||||
/* Configure the default Alternate Function in current IO */
|
||||
GPIOx->AFR[position >> 3u] &= ~(0xFu << ((position & 0x07u) * 4u)) ;
|
||||
|
||||
/* Configure the default value for IO Speed */
|
||||
GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2u));
|
||||
|
||||
/* Configure the default value IO Output Type */
|
||||
GPIOx->OTYPER &= ~(GPIO_OTYPER_OT0 << position) ;
|
||||
|
||||
/* Deactivate the Pull-up and Pull-down resistor for the current IO */
|
||||
GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2u));
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Exported_Functions_Group2
|
||||
* @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Read the specified input port pin.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Pin specifies the port bit to read.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @retval The input port pin value.
|
||||
*/
|
||||
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
GPIO_PinState bitstatus;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
if ((GPIOx->IDR & GPIO_Pin) != 0x00u)
|
||||
{
|
||||
bitstatus = GPIO_PIN_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = GPIO_PIN_RESET;
|
||||
}
|
||||
return bitstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set or clear the selected data port bit.
|
||||
* @note This function uses GPIOx_BSRR and GPIOx_BRR registers to allow atomic read/modify
|
||||
* accesses. In this way, there is no risk of an IRQ occurring between
|
||||
* the read and the modify access.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Pin specifies the port bit to be written.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @param PinState specifies the value to be written to the selected bit.
|
||||
* This parameter can be one of the GPIO_PinState enum values:
|
||||
* @arg GPIO_PIN_RESET: to clear the port pin
|
||||
* @arg GPIO_PIN_SET: to set the port pin
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
assert_param(IS_GPIO_PIN_ACTION(PinState));
|
||||
|
||||
if (PinState != GPIO_PIN_RESET)
|
||||
{
|
||||
GPIOx->BSRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOx->BRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggle the specified GPIO pin.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Pin specifies the pin to be toggled.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
if ((GPIOx->ODR & GPIO_Pin) != 0x00u)
|
||||
{
|
||||
GPIOx->BRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOx->BSRR = (uint32_t)GPIO_Pin;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock GPIO Pins configuration registers.
|
||||
* @note The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
|
||||
* GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
|
||||
* @note The configuration of the locked GPIO pins can no longer be modified
|
||||
* until the next reset.
|
||||
* @param GPIOx where x can be (A..F) to select the GPIO peripheral for PY32F0xx family
|
||||
* @param GPIO_Pin specifies the port bits to be locked.
|
||||
* This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
|
||||
* @retval None
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
__IO uint32_t tmp = GPIO_LCKR_LCKK;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
/* Apply lock key write sequence */
|
||||
tmp |= GPIO_Pin;
|
||||
/* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
|
||||
GPIOx->LCKR = tmp;
|
||||
/* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
|
||||
GPIOx->LCKR = GPIO_Pin;
|
||||
/* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
|
||||
GPIOx->LCKR = tmp;
|
||||
/* Read LCKK register. This read is mandatory to complete key lock sequence */
|
||||
tmp = GPIOx->LCKR;
|
||||
|
||||
/* read again in order to confirm lock is active */
|
||||
if ((GPIOx->LCKR & __GPIO_LOCK_KEY_Msk) != 0x00u)
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(GPIO_Pin);
|
||||
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_GPIO_EXTI_Callback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* @brief Handle EXTI interrupt request.
|
||||
* @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
|
||||
{
|
||||
/* EXTI line interrupt detected */
|
||||
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
||||
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
7203
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_i2c.c
Normal file
7203
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_i2c.c
Normal file
File diff suppressed because it is too large
Load Diff
2661
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_irda.c
Normal file
2661
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_irda.c
Normal file
@@ -0,0 +1,2661 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_irda.c
|
||||
* @author MCU Application Team
|
||||
* @brief IRDA HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the IrDA SIR ENDEC block (IrDA):
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral Control functions
|
||||
* + Peripheral State and Errors functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The IRDA HAL driver can be used as follows:
|
||||
|
||||
(#) Declare a IRDA_HandleTypeDef handle structure (eg. IRDA_HandleTypeDef hirda).
|
||||
(#) Initialize the IRDA low level resources by implementing the HAL_IRDA_MspInit() API:
|
||||
(##) Enable the USARTx interface clock.
|
||||
(##) IRDA pins configuration:
|
||||
(+++) Enable the clock for the IRDA GPIOs.
|
||||
(+++) Configure IRDA pins as alternate function pull-up.
|
||||
(##) NVIC configuration if you need to use interrupt process (HAL_IRDA_Transmit_IT()
|
||||
and HAL_IRDA_Receive_IT() APIs):
|
||||
(+++) Configure the USARTx interrupt priority.
|
||||
(+++) Enable the NVIC USART IRQ handle.
|
||||
(##) DMA Configuration if you need to use DMA process (HAL_IRDA_Transmit_DMA()
|
||||
and HAL_IRDA_Receive_DMA() APIs):
|
||||
(+++) Declare a DMA handle structure for the Tx/Rx channel.
|
||||
(+++) Enable the DMAx interface clock.
|
||||
(+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
|
||||
(+++) Configure the DMA Tx/Rx channel.
|
||||
(+++) Associate the initialized DMA handle to the IRDA DMA Tx/Rx handle.
|
||||
(+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
|
||||
(+++) Configure the IRDAx interrupt priority and enable the NVIC USART IRQ handle
|
||||
(used for last byte sending completion detection in DMA non circular mode)
|
||||
|
||||
(#) Program the Baud Rate, Word Length, Parity, IrDA Mode, Prescaler
|
||||
and Mode(Receiver/Transmitter) in the hirda Init structure.
|
||||
|
||||
(#) Initialize the IRDA registers by calling the HAL_IRDA_Init() API:
|
||||
(++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
|
||||
by calling the customized HAL_IRDA_MspInit() API.
|
||||
|
||||
-@@- The specific IRDA interrupts (Transmission complete interrupt,
|
||||
RXNE interrupt and Error Interrupts) will be managed using the macros
|
||||
__HAL_IRDA_ENABLE_IT() and __HAL_IRDA_DISABLE_IT() inside the transmit and receive process.
|
||||
|
||||
(#) Three operation modes are available within this driver :
|
||||
|
||||
*** Polling mode IO operation ***
|
||||
=================================
|
||||
[..]
|
||||
(+) Send an amount of data in blocking mode using HAL_IRDA_Transmit()
|
||||
(+) Receive an amount of data in blocking mode using HAL_IRDA_Receive()
|
||||
|
||||
*** Interrupt mode IO operation ***
|
||||
===================================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode using HAL_IRDA_Transmit_IT()
|
||||
(+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode using HAL_IRDA_Receive_IT()
|
||||
(+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_ErrorCallback
|
||||
|
||||
*** DMA mode IO operation ***
|
||||
=============================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode (DMA) using HAL_IRDA_Transmit_DMA()
|
||||
(+) At transmission end of half transfer HAL_IRDA_TxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_TxHalfCpltCallback
|
||||
(+) At transmission end of transfer HAL_IRDA_TxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode (DMA) using HAL_IRDA_Receive_DMA()
|
||||
(+) At reception end of half transfer HAL_IRDA_RxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_RxHalfCpltCallback
|
||||
(+) At reception end of transfer HAL_IRDA_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_IRDA_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_IRDA_ErrorCallback
|
||||
(+) Pause the DMA Transfer using HAL_IRDA_DMAPause()
|
||||
(+) Resume the DMA Transfer using HAL_IRDA_DMAResume()
|
||||
(+) Stop the DMA Transfer using HAL_IRDA_DMAStop()
|
||||
|
||||
*** IRDA HAL driver macros list ***
|
||||
===================================
|
||||
[..]
|
||||
Below the list of most used macros in IRDA HAL driver.
|
||||
|
||||
(+) __HAL_IRDA_ENABLE: Enable the IRDA peripheral
|
||||
(+) __HAL_IRDA_DISABLE: Disable the IRDA peripheral
|
||||
(+) __HAL_IRDA_GET_FLAG : Check whether the specified IRDA flag is set or not
|
||||
(+) __HAL_IRDA_CLEAR_FLAG : Clear the specified IRDA pending flag
|
||||
(+) __HAL_IRDA_ENABLE_IT: Enable the specified IRDA interrupt
|
||||
(+) __HAL_IRDA_DISABLE_IT: Disable the specified IRDA interrupt
|
||||
(+) __HAL_IRDA_GET_IT_SOURCE: Check whether the specified IRDA interrupt has occurred or not
|
||||
|
||||
[..]
|
||||
(@) You can refer to the IRDA HAL driver header file for more useful macros
|
||||
|
||||
##### Callback registration #####
|
||||
==================================
|
||||
|
||||
[..]
|
||||
The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS when set to 1
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
|
||||
[..]
|
||||
Use Function @ref HAL_IRDA_RegisterCallback() to register a user callback.
|
||||
Function @ref HAL_IRDA_RegisterCallback() allows to register following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
|
||||
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
|
||||
(+) MspInitCallback : IRDA MspInit.
|
||||
(+) MspDeInitCallback : IRDA MspDeInit.
|
||||
This function takes as parameters the HAL peripheral handle, the Callback ID
|
||||
and a pointer to the user callback function.
|
||||
|
||||
[..]
|
||||
Use function @ref HAL_IRDA_UnRegisterCallback() to reset a callback to the default
|
||||
weak (surcharged) function.
|
||||
@ref HAL_IRDA_UnRegisterCallback() takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
This function allows to reset following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
|
||||
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
|
||||
(+) MspInitCallback : IRDA MspInit.
|
||||
(+) MspDeInitCallback : IRDA MspDeInit.
|
||||
|
||||
[..]
|
||||
By default, after the @ref HAL_IRDA_Init() and when the state is HAL_IRDA_STATE_RESET
|
||||
all callbacks are set to the corresponding weak (surcharged) functions:
|
||||
examples @ref HAL_IRDA_TxCpltCallback(), @ref HAL_IRDA_RxHalfCpltCallback().
|
||||
Exception done for MspInit and MspDeInit functions that are respectively
|
||||
reset to the legacy weak (surcharged) functions in the @ref HAL_IRDA_Init()
|
||||
and @ref HAL_IRDA_DeInit() only when these callbacks are null (not registered beforehand).
|
||||
If not, MspInit or MspDeInit are not null, the @ref HAL_IRDA_Init() and @ref HAL_IRDA_DeInit()
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
|
||||
|
||||
[..]
|
||||
Callbacks can be registered/unregistered in HAL_IRDA_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit that can be registered/unregistered
|
||||
in HAL_IRDA_STATE_READY or HAL_IRDA_STATE_RESET state, thus registered (user)
|
||||
MspInit/DeInit callbacks can be used during the Init/DeInit.
|
||||
In that case first register the MspInit/MspDeInit user callbacks
|
||||
using @ref HAL_IRDA_RegisterCallback() before calling @ref HAL_IRDA_DeInit()
|
||||
or @ref HAL_IRDA_Init() function.
|
||||
|
||||
[..]
|
||||
When The compilation define USE_HAL_IRDA_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available
|
||||
and weak (surcharged) callbacks are used.
|
||||
|
||||
@endverbatim
|
||||
[..]
|
||||
(@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
the possible IRDA frame formats are as listed in the following table:
|
||||
+-------------------------------------------------------------+
|
||||
| M bit | PCE bit | IRDA frame |
|
||||
|---------------------|---------------------------------------|
|
||||
| 0 | 0 | | SB | 8 bit data | 1 STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 0 | 1 | | SB | 7 bit data | PB | 1 STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 0 | | SB | 9 bit data | 1 STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 1 | | SB | 8 bit data | PB | 1 STB | |
|
||||
+-------------------------------------------------------------+
|
||||
******************************************************************************
|
||||
* @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 IRDA IRDA
|
||||
* @brief HAL IRDA module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @addtogroup IRDA_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda);
|
||||
static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda);
|
||||
static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda);
|
||||
static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda);
|
||||
static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMAError(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
|
||||
static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda);
|
||||
static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup IRDA_Exported_Functions IrDA Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup IRDA_Exported_Functions_Group1 IrDA Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
|
||||
==============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
|
||||
in asynchronous IrDA mode.
|
||||
(+) For the asynchronous mode only these parameters can be configured:
|
||||
(++) BaudRate
|
||||
(++) WordLength
|
||||
(++) Parity: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
please refer to Reference manual for possible IRDA frame formats.
|
||||
(++) Prescaler: A pulse of width less than two and greater than one PSC period(s) may or may
|
||||
not be rejected. The receiver set up time should be managed by software. The IrDA physical layer
|
||||
specification specifies a minimum of 10 ms delay between transmission and
|
||||
reception (IrDA is a half duplex protocol).
|
||||
(++) Mode: Receiver/transmitter modes
|
||||
(++) IrDAMode: the IrDA can operate in the Normal mode or in the Low power mode.
|
||||
[..]
|
||||
The HAL_IRDA_Init() API follows IRDA configuration procedures (details for the procedures
|
||||
are available in reference manual).
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the IRDA mode according to the specified
|
||||
* parameters in the IRDA_InitTypeDef and create the associated handle.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Init(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Check the IRDA handle allocation */
|
||||
if (hirda == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the IRDA instance parameters */
|
||||
assert_param(IS_IRDA_INSTANCE(hirda->Instance));
|
||||
/* Check the IRDA mode parameter in the IRDA handle */
|
||||
assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
|
||||
|
||||
if (hirda->gState == HAL_IRDA_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hirda->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
|
||||
IRDA_InitCallbacksToDefault(hirda);
|
||||
|
||||
if (hirda->MspInitCallback == NULL)
|
||||
{
|
||||
hirda->MspInitCallback = HAL_IRDA_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
hirda->MspInitCallback(hirda);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK */
|
||||
HAL_IRDA_MspInit(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
hirda->gState = HAL_IRDA_STATE_BUSY;
|
||||
|
||||
/* Disable the IRDA peripheral */
|
||||
__HAL_IRDA_DISABLE(hirda);
|
||||
|
||||
/* Set the IRDA communication parameters */
|
||||
IRDA_SetConfig(hirda);
|
||||
|
||||
/* In IrDA mode, the following bits must be kept cleared:
|
||||
- LINEN, STOP and CLKEN bits in the USART_CR2 register,
|
||||
- SCEN and HDSEL bits in the USART_CR3 register.*/
|
||||
CLEAR_BIT(hirda->Instance->CR2, (USART_CR2_LINEN | USART_CR2_STOP | USART_CR2_CLKEN));
|
||||
CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_SCEN | USART_CR3_HDSEL));
|
||||
|
||||
/* Enable the IRDA peripheral */
|
||||
__HAL_IRDA_ENABLE(hirda);
|
||||
|
||||
/* Set the prescaler */
|
||||
MODIFY_REG(hirda->Instance->GTPR, USART_GTPR_PSC, hirda->Init.Prescaler);
|
||||
|
||||
/* Configure the IrDA mode */
|
||||
MODIFY_REG(hirda->Instance->CR3, USART_CR3_IRLP, hirda->Init.IrDAMode);
|
||||
|
||||
/* Enable the IrDA mode by setting the IREN bit in the CR3 register */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_IREN);
|
||||
|
||||
/* Initialize the IRDA state*/
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the IRDA peripheral
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_DeInit(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Check the IRDA handle allocation */
|
||||
if (hirda == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_IRDA_INSTANCE(hirda->Instance));
|
||||
|
||||
hirda->gState = HAL_IRDA_STATE_BUSY;
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_IRDA_DISABLE(hirda);
|
||||
|
||||
/* DeInit the low level hardware */
|
||||
#if USE_HAL_IRDA_REGISTER_CALLBACKS == 1
|
||||
if (hirda->MspDeInitCallback == NULL)
|
||||
{
|
||||
hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
|
||||
}
|
||||
/* DeInit the low level hardware */
|
||||
hirda->MspDeInitCallback(hirda);
|
||||
#else
|
||||
HAL_IRDA_MspDeInit(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
|
||||
hirda->gState = HAL_IRDA_STATE_RESET;
|
||||
hirda->RxState = HAL_IRDA_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA MSP Init.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_MspInit(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_MspInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA MSP DeInit.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_MspDeInit(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_MspDeInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User IRDA Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param hirda irda handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_RegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID, pIRDA_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
if (hirda->gState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
|
||||
hirda->TxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_TX_COMPLETE_CB_ID :
|
||||
hirda->TxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
|
||||
hirda->RxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_RX_COMPLETE_CB_ID :
|
||||
hirda->RxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ERROR_CB_ID :
|
||||
hirda->ErrorCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_COMPLETE_CB_ID :
|
||||
hirda->AbortCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
|
||||
hirda->AbortTransmitCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
|
||||
hirda->AbortReceiveCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPINIT_CB_ID :
|
||||
hirda->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPDEINIT_CB_ID :
|
||||
hirda->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (hirda->gState == HAL_IRDA_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_IRDA_MSPINIT_CB_ID :
|
||||
hirda->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPDEINIT_CB_ID :
|
||||
hirda->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister an IRDA callback
|
||||
* IRDA callback is redirected to the weak predefined callback
|
||||
* @param hirda irda handle
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_IRDA_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
|
||||
* @arg @ref HAL_IRDA_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_IRDA_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_UnRegisterCallback(IRDA_HandleTypeDef *hirda, HAL_IRDA_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
if (HAL_IRDA_STATE_READY == hirda->gState)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_IRDA_TX_HALFCOMPLETE_CB_ID :
|
||||
hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_TX_COMPLETE_CB_ID :
|
||||
hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_RX_HALFCOMPLETE_CB_ID :
|
||||
hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_RX_COMPLETE_CB_ID :
|
||||
hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ERROR_CB_ID :
|
||||
hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_COMPLETE_CB_ID :
|
||||
hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_TRANSMIT_COMPLETE_CB_ID :
|
||||
hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_ABORT_RECEIVE_COMPLETE_CB_ID :
|
||||
hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPINIT_CB_ID :
|
||||
hirda->MspInitCallback = HAL_IRDA_MspInit; /* Legacy weak MspInitCallback */
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPDEINIT_CB_ID :
|
||||
hirda->MspDeInitCallback = HAL_IRDA_MspDeInit; /* Legacy weak MspDeInitCallback */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_IRDA_STATE_RESET == hirda->gState)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_IRDA_MSPINIT_CB_ID :
|
||||
hirda->MspInitCallback = HAL_IRDA_MspInit;
|
||||
break;
|
||||
|
||||
case HAL_IRDA_MSPDEINIT_CB_ID :
|
||||
hirda->MspDeInitCallback = HAL_IRDA_MspDeInit;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IRDA_Exported_Functions_Group2 IO operation functions
|
||||
* @brief IRDA Transmit and Receive functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### IO operation functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the IRDA data transfers.
|
||||
IrDA is a half duplex communication protocol. If the Transmitter is busy, any data
|
||||
on the IrDA receive line will be ignored by the IrDA decoder and if the Receiver
|
||||
is busy, data on the TX from the USART to IrDA will not be encoded by IrDA.
|
||||
While receiving data, transmission should be avoided as the data to be transmitted
|
||||
could be corrupted.
|
||||
|
||||
(#) 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.
|
||||
(++) Non-Blocking mode: The communication is performed using Interrupts
|
||||
or DMA, these API's return the HAL status.
|
||||
The end of the data processing will be indicated through the
|
||||
dedicated IRDA IRQ when using Interrupt mode or the DMA IRQ when
|
||||
using DMA mode.
|
||||
The HAL_IRDA_TxCpltCallback(), HAL_IRDA_RxCpltCallback() user callbacks
|
||||
will be executed respectively at the end of the Transmit or Receive process
|
||||
The HAL_IRDA_ErrorCallback() user callback will be executed when a communication error is detected
|
||||
|
||||
(#) Blocking mode APIs are :
|
||||
(++) HAL_IRDA_Transmit()
|
||||
(++) HAL_IRDA_Receive()
|
||||
|
||||
(#) Non Blocking mode APIs with Interrupt are :
|
||||
(++) HAL_IRDA_Transmit_IT()
|
||||
(++) HAL_IRDA_Receive_IT()
|
||||
(++) HAL_IRDA_IRQHandler()
|
||||
|
||||
(#) Non Blocking mode functions with DMA are :
|
||||
(++) HAL_IRDA_Transmit_DMA()
|
||||
(++) HAL_IRDA_Receive_DMA()
|
||||
(++) HAL_IRDA_DMAPause()
|
||||
(++) HAL_IRDA_DMAResume()
|
||||
(++) HAL_IRDA_DMAStop()
|
||||
|
||||
(#) A set of Transfer Complete Callbacks are provided in Non Blocking mode:
|
||||
(++) HAL_IRDA_TxHalfCpltCallback()
|
||||
(++) HAL_IRDA_TxCpltCallback()
|
||||
(++) HAL_IRDA_RxHalfCpltCallback()
|
||||
(++) HAL_IRDA_RxCpltCallback()
|
||||
(++) HAL_IRDA_ErrorCallback()
|
||||
|
||||
(#) Non-Blocking mode transfers could be aborted using Abort API's :
|
||||
(+) HAL_IRDA_Abort()
|
||||
(+) HAL_IRDA_AbortTransmit()
|
||||
(+) HAL_IRDA_AbortReceive()
|
||||
(+) HAL_IRDA_Abort_IT()
|
||||
(+) HAL_IRDA_AbortTransmit_IT()
|
||||
(+) HAL_IRDA_AbortReceive_IT()
|
||||
|
||||
(#) For Abort services based on interrupts (HAL_IRDA_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
|
||||
(+) HAL_IRDA_AbortCpltCallback()
|
||||
(+) HAL_IRDA_AbortTransmitCpltCallback()
|
||||
(+) HAL_IRDA_AbortReceiveCpltCallback()
|
||||
|
||||
(#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
|
||||
Errors are handled as follows :
|
||||
(+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
|
||||
to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
|
||||
Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
|
||||
and HAL_IRDA_ErrorCallback() user callback is executed. Transfer is kept ongoing on IRDA side.
|
||||
If user wants to abort it, Abort services should be called by user.
|
||||
(+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
|
||||
This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
|
||||
Error code is set to allow user to identify error type, and HAL_IRDA_ErrorCallback() user callback is executed.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sends an amount of data in blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the sent data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @param Timeout Specify timeout value.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Transmit(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (hirda->gState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->gState = HAL_IRDA_STATE_BUSY_TX;
|
||||
|
||||
/* Init tickstart for timeout managment*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
hirda->TxXferSize = Size;
|
||||
hirda->TxXferCount = Size;
|
||||
while (hirda->TxXferCount > 0U)
|
||||
{
|
||||
hirda->TxXferCount--;
|
||||
if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
|
||||
{
|
||||
if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pData;
|
||||
hirda->Instance->DR = (*tmp & (uint16_t)0x01FF);
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
pData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pData += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
hirda->Instance->DR = (*pData++ & (uint8_t)0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/* At end of Tx process, restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive an amount of data in blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the received data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @param Timeout Specify timeout value
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Receive(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (hirda->RxState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
|
||||
|
||||
/* Init tickstart for timeout managment*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
hirda->RxXferSize = Size;
|
||||
hirda->RxXferCount = Size;
|
||||
|
||||
/* Check the remain data to be received */
|
||||
while (hirda->RxXferCount > 0U)
|
||||
{
|
||||
hirda->RxXferCount--;
|
||||
|
||||
if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
|
||||
{
|
||||
if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pData ;
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x01FF);
|
||||
pData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(hirda->Instance->DR & (uint16_t)0x00FF);
|
||||
pData += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IRDA_WaitOnFlagUntilTimeout(hirda, IRDA_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
*pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*pData++ = (uint8_t)(hirda->Instance->DR & (uint8_t)0x007F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* At end of Rx process, restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an amount of data in non blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the sent data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (hirda->gState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->pTxBuffPtr = pData;
|
||||
hirda->TxXferSize = Size;
|
||||
hirda->TxXferCount = Size;
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->gState = HAL_IRDA_STATE_BUSY_TX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
/* Enable the IRDA Transmit Data Register Empty Interrupt */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receive an amount of data in non blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the received data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Receive_IT(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (hirda->RxState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->pRxBuffPtr = pData;
|
||||
hirda->RxXferSize = Size;
|
||||
hirda->RxXferCount = Size;
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
/* Enable the IRDA Parity Error and Data Register Not Empty Interrupts */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||||
|
||||
/* Enable the IRDA Error Interrupt: (Frame error, Noise error, Overrun error) */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an amount of data in DMA mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the sent data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Transmit_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (hirda->gState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->pTxBuffPtr = pData;
|
||||
hirda->TxXferSize = Size;
|
||||
hirda->TxXferCount = Size;
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->gState = HAL_IRDA_STATE_BUSY_TX;
|
||||
|
||||
/* Set the IRDA DMA transfer complete callback */
|
||||
hirda->hdmatx->XferCpltCallback = IRDA_DMATransmitCplt;
|
||||
|
||||
/* Set the IRDA DMA half transfer complete callback */
|
||||
hirda->hdmatx->XferHalfCpltCallback = IRDA_DMATransmitHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
hirda->hdmatx->XferErrorCallback = IRDA_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the IRDA transmit DMA channel */
|
||||
tmp = (uint32_t *)&pData;
|
||||
HAL_DMA_Start_IT(hirda->hdmatx, *(uint32_t *)tmp, (uint32_t)&hirda->Instance->DR, Size);
|
||||
|
||||
/* Clear the TC flag in the SR register by writing 0 to it */
|
||||
__HAL_IRDA_CLEAR_FLAG(hirda, IRDA_FLAG_TC);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
/* Enable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in DMA mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M1-M0 = 01),
|
||||
* the received data is handled as a set of u16. In this case, Size must reflect the number
|
||||
* of u16 available through pData.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @note When the IRDA parity is enabled (PCE = 1) the data received contain the parity bit.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Receive_DMA(IRDA_HandleTypeDef *hirda, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (hirda->RxState == HAL_IRDA_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
hirda->pRxBuffPtr = pData;
|
||||
hirda->RxXferSize = Size;
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
hirda->RxState = HAL_IRDA_STATE_BUSY_RX;
|
||||
|
||||
/* Set the IRDA DMA transfer complete callback */
|
||||
hirda->hdmarx->XferCpltCallback = IRDA_DMAReceiveCplt;
|
||||
|
||||
/* Set the IRDA DMA half transfer complete callback */
|
||||
hirda->hdmarx->XferHalfCpltCallback = IRDA_DMAReceiveHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
hirda->hdmarx->XferErrorCallback = IRDA_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
tmp = (uint32_t *)&pData;
|
||||
HAL_DMA_Start_IT(hirda->hdmarx, (uint32_t)&hirda->Instance->DR, *(uint32_t *)tmp, Size);
|
||||
|
||||
/* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
|
||||
__HAL_IRDA_CLEAR_OREFLAG(hirda);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
/* Enable the IRDA Parity Error Interrupt */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Enable the IRDA Error Interrupt: (Frame error, Noise error, Overrun error) */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pauses the DMA Transfer.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_DMAPause(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
/* Disable the IRDA DMA Tx request */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the IRDA DMA Rx request */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resumes the DMA Transfer.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_DMAResume(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hirda);
|
||||
|
||||
if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
|
||||
{
|
||||
/* Enable the IRDA DMA Tx request */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
|
||||
{
|
||||
/* Clear the Overrun flag before resuming the Rx transfer */
|
||||
__HAL_IRDA_CLEAR_OREFLAG(hirda);
|
||||
|
||||
/* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the IRDA DMA Rx request */
|
||||
SET_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the DMA Transfer.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_DMAStop(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
/* The Lock is not implemented on this API to allow the user application
|
||||
to call the HAL IRDA API under callbacks HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback():
|
||||
when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
|
||||
and the correspond call back is executed HAL_IRDA_TxCpltCallback() / HAL_IRDA_RxCpltCallback()
|
||||
*/
|
||||
|
||||
/* Stop IRDA DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the IRDA DMA Tx channel */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(hirda->hdmatx);
|
||||
}
|
||||
IRDA_EndTxTransfer(hirda);
|
||||
}
|
||||
|
||||
/* Stop IRDA DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(hirda->hdmarx);
|
||||
}
|
||||
IRDA_EndRxTransfer(hirda);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfers (blocking mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP Interrupts
|
||||
* - 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.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Abort(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the IRDA DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(hirda->hdmatx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the IRDA DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(hirda->hdmarx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
|
||||
/* Restore hirda->RxState and hirda->gState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Transmit transfer (blocking mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP Interrupts
|
||||
* - 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.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_AbortTransmit(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
/* Disable the IRDA DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the IRDA DMA Tx channel : use blocking DMA Abort API (no callback) */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(hirda->hdmatx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset Tx transfer counter */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Receive transfer (blocking mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP Interrupts
|
||||
* - 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.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_AbortReceive(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the IRDA DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel : use blocking DMA Abort API (no callback) */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(hirda->hdmarx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset Rx transfer counter */
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfers (Interrupt mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP Interrupts
|
||||
* - 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).
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_Abort_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t AbortCplt = 0x01U;
|
||||
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* If DMA Tx and/or DMA Rx Handles are associated to IRDA Handle, DMA Abort complete callbacks should be initialised
|
||||
before any call to DMA Abort functions */
|
||||
/* DMA Tx Handle is valid */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if IRDA DMA Tx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
hirda->hdmatx->XferAbortCallback = IRDA_DMATxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
/* DMA Rx Handle is valid */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if IRDA DMA Rx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
hirda->hdmarx->XferAbortCallback = IRDA_DMARxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the IRDA DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
/* Disable DMA Tx at IRDA level */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
/* IRDA Tx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA TX */
|
||||
if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
|
||||
{
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the IRDA DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* IRDA Rx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
|
||||
{
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
AbortCplt = 0x01U;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if no DMA abort complete callback execution is required => call user Abort Complete callback */
|
||||
if (AbortCplt == 0x01U)
|
||||
{
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
|
||||
/* Restore hirda->gState and hirda->RxState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
hirda->AbortCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_IRDA_AbortCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Transmit transfer (Interrupt mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable IRDA Interrupts (Tx)
|
||||
* - 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).
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_AbortTransmit_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
/* Disable the IRDA DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the IRDA DMA Tx channel : use non blocking DMA Abort API (callback) */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback :
|
||||
will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
|
||||
hirda->hdmatx->XferAbortCallback = IRDA_DMATxOnlyAbortCallback;
|
||||
|
||||
/* Abort DMA TX */
|
||||
if (HAL_DMA_Abort_IT(hirda->hdmatx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly hirda->hdmatx->XferAbortCallback function in case of error */
|
||||
hirda->hdmatx->XferAbortCallback(hirda->hdmatx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Tx transfer counter */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
hirda->AbortTransmitCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_IRDA_AbortTransmitCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Tx transfer counter */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
hirda->AbortTransmitCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_IRDA_AbortTransmitCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Receive transfer (Interrupt mode).
|
||||
* @param hirda IRDA handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP Interrupts
|
||||
* - 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).
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IRDA_AbortReceive_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the IRDA DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel : use non blocking DMA Abort API (callback) */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback :
|
||||
will lead to call HAL_IRDA_AbortCpltCallback() at end of DMA abort procedure */
|
||||
hirda->hdmarx->XferAbortCallback = IRDA_DMARxOnlyAbortCallback;
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly hirda->hdmarx->XferAbortCallback function in case of error */
|
||||
hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Rx transfer counter */
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
hirda->AbortReceiveCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_IRDA_AbortReceiveCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Rx transfer counter */
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
hirda->AbortReceiveCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_IRDA_AbortReceiveCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles IRDA interrupt request.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_IRDA_IRQHandler(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t isrflags = READ_REG(hirda->Instance->SR);
|
||||
uint32_t cr1its = READ_REG(hirda->Instance->CR1);
|
||||
uint32_t cr3its = READ_REG(hirda->Instance->CR3);
|
||||
uint32_t errorflags = 0x00U;
|
||||
uint32_t dmarequest = 0x00U;
|
||||
|
||||
/* If no error occurs */
|
||||
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
|
||||
if (errorflags == RESET)
|
||||
{
|
||||
/* IRDA in mode Receiver -----------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
IRDA_Receive_IT(hirda);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If some errors occur */
|
||||
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
|
||||
{
|
||||
/* IRDA parity error interrupt occurred -------------------------------*/
|
||||
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
|
||||
{
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_PE;
|
||||
}
|
||||
|
||||
/* IRDA noise error interrupt occurred --------------------------------*/
|
||||
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_NE;
|
||||
}
|
||||
|
||||
/* IRDA frame error interrupt occurred --------------------------------*/
|
||||
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_FE;
|
||||
}
|
||||
|
||||
/* IRDA Over-Run interrupt occurred -----------------------------------*/
|
||||
if (((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_ORE;
|
||||
}
|
||||
/* Call IRDA Error Call back function if need be -----------------------*/
|
||||
if (hirda->ErrorCode != HAL_IRDA_ERROR_NONE)
|
||||
{
|
||||
/* IRDA in mode Receiver ---------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
IRDA_Receive_IT(hirda);
|
||||
}
|
||||
|
||||
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
|
||||
consider error as blocking */
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
if (((hirda->ErrorCode & HAL_IRDA_ERROR_ORE) != RESET) || dmarequest)
|
||||
{
|
||||
/* Blocking error : transfer is aborted
|
||||
Set the IRDA state ready to be able to start again the process,
|
||||
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
|
||||
IRDA_EndRxTransfer(hirda);
|
||||
|
||||
/* Disable the IRDA DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the IRDA DMA Rx channel */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
/* Set the IRDA DMA Abort callback :
|
||||
will lead to call HAL_IRDA_ErrorCallback() at end of DMA abort procedure */
|
||||
hirda->hdmarx->XferAbortCallback = IRDA_DMAAbortOnError;
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(hirda->hdmarx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly XferAbortCallback function in case of error */
|
||||
hirda->hdmarx->XferAbortCallback(hirda->hdmarx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered user error callback */
|
||||
hirda->ErrorCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak user error callback */
|
||||
HAL_IRDA_ErrorCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered user error callback */
|
||||
hirda->ErrorCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak user error callback */
|
||||
HAL_IRDA_ErrorCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non Blocking error : transfer could go on.
|
||||
Error is notified to user through user error callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered user error callback */
|
||||
hirda->ErrorCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak user error callback */
|
||||
HAL_IRDA_ErrorCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} /* End if some error occurs */
|
||||
|
||||
/* IRDA in mode Transmitter ------------------------------------------------*/
|
||||
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
|
||||
{
|
||||
IRDA_Transmit_IT(hirda);
|
||||
return;
|
||||
}
|
||||
|
||||
/* IRDA in mode Transmitter end --------------------------------------------*/
|
||||
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
|
||||
{
|
||||
IRDA_EndTransmit_IT(hirda);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Transfer complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_TxCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_TxCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Half Transfer completed callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_TxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_TxHalfCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Transfer complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_RxCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_RxCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Half Transfer complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_RxHalfCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_RxHalfCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA error callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_ErrorCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_ErrorCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA Abort Complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_AbortCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_AbortCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA Abort Transmit Complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_AbortTransmitCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_AbortTransmitCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IRDA Abort Receive Complete callback.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_IRDA_AbortReceiveCpltCallback(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hirda);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_IRDA_AbortReceiveCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IRDA_Exported_Functions_Group3 Peripheral State and Errors functions
|
||||
* @brief IRDA State and Errors functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral State and Errors functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to return the State of IrDA
|
||||
communication process and also return Peripheral Errors occurred during communication process
|
||||
(+) HAL_IRDA_GetState() API can be helpful to check in run-time the state of the IrDA peripheral.
|
||||
(+) HAL_IRDA_GetError() check in run-time errors that could be occurred during communication.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the IRDA state.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_IRDA_StateTypeDef HAL_IRDA_GetState(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t temp1 = 0x00U, temp2 = 0x00U;
|
||||
temp1 = hirda->gState;
|
||||
temp2 = hirda->RxState;
|
||||
|
||||
return (HAL_IRDA_StateTypeDef)(temp1 | temp2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the IRDA error code
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA.
|
||||
* @retval IRDA Error Code
|
||||
*/
|
||||
uint32_t HAL_IRDA_GetError(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
return hirda->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup IRDA_Private_Functions IRDA Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Initialize the callbacks to their default values.
|
||||
* @param hirda IRDA handle.
|
||||
* @retval none
|
||||
*/
|
||||
void IRDA_InitCallbacksToDefault(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Init the IRDA Callback settings */
|
||||
hirda->TxHalfCpltCallback = HAL_IRDA_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
hirda->TxCpltCallback = HAL_IRDA_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
hirda->RxHalfCpltCallback = HAL_IRDA_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
hirda->RxCpltCallback = HAL_IRDA_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
hirda->ErrorCallback = HAL_IRDA_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
hirda->AbortCpltCallback = HAL_IRDA_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
hirda->AbortTransmitCpltCallback = HAL_IRDA_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
|
||||
hirda->AbortReceiveCpltCallback = HAL_IRDA_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
|
||||
|
||||
}
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA transmit process complete callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMATransmitCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
/* DMA Normal mode */
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
hirda->TxXferCount = 0U;
|
||||
|
||||
/* Disable the DMA transfer for transmit request by resetting the DMAT bit
|
||||
in the IRDA CR3 register */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Enable the IRDA Transmit Complete Interrupt */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
|
||||
}
|
||||
/* DMA Circular mode */
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx complete callback */
|
||||
hirda->TxCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Tx complete callback */
|
||||
HAL_IRDA_TxCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA receive process half complete callback
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMATransmitHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Half complete callback */
|
||||
hirda->TxHalfCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Tx complete callback */
|
||||
HAL_IRDA_TxHalfCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA receive process complete callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* DMA Normal mode */
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
hirda->RxXferCount = 0U;
|
||||
|
||||
/* Disable PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the DMA transfer for the receiver request by resetting the DMAR bit
|
||||
in the IRDA CR3 register */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* At end of Rx process, restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
}
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx complete callback */
|
||||
hirda->RxCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Rx complete callback */
|
||||
HAL_IRDA_RxCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA receive process half complete callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMAReceiveHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Rx Half complete callback*/
|
||||
hirda->RxHalfCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Rx Half complete callback */
|
||||
HAL_IRDA_RxHalfCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA communication error callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMAError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Stop IRDA DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((hirda->gState == HAL_IRDA_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
hirda->TxXferCount = 0U;
|
||||
IRDA_EndTxTransfer(hirda);
|
||||
}
|
||||
|
||||
/* Stop IRDA DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(hirda->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((hirda->RxState == HAL_IRDA_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
hirda->RxXferCount = 0U;
|
||||
IRDA_EndRxTransfer(hirda);
|
||||
}
|
||||
|
||||
hirda->ErrorCode |= HAL_IRDA_ERROR_DMA;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered user error callback */
|
||||
hirda->ErrorCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak user error callback */
|
||||
HAL_IRDA_ErrorCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles IRDA Communication Timeout.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA.
|
||||
* @param Flag specifies the IRDA flag to check.
|
||||
* @param Status The new Flag status (SET or RESET).
|
||||
* @param Tickstart Tick start value
|
||||
* @param Timeout Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef IRDA_WaitOnFlagUntilTimeout(IRDA_HandleTypeDef *hirda, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
|
||||
{
|
||||
/* Wait until flag is set */
|
||||
while ((__HAL_IRDA_GET_FLAG(hirda, Flag) ? SET : RESET) == Status)
|
||||
{
|
||||
/* Check for the Timeout */
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
|
||||
{
|
||||
/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hirda);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End ongoing Tx transfer on IRDA peripheral (following error detection or Transmit completion).
|
||||
* @param hirda IRDA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_EndTxTransfer(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
/* At end of Tx process, restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End ongoing Rx transfer on IRDA peripheral (following error detection or Reception completion).
|
||||
* @param hirda IRDA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_EndRxTransfer(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* At end of Rx process, restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA communication abort callback, when initiated by HAL services on Error
|
||||
* (To be called at end of DMA Abort procedure following error occurrence).
|
||||
* @param hdma DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMAAbortOnError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
hirda->RxXferCount = 0x00U;
|
||||
hirda->TxXferCount = 0x00U;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered user error callback */
|
||||
hirda->ErrorCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak user error callback */
|
||||
HAL_IRDA_ErrorCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA 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.
|
||||
* @param hdma DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
hirda->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (hirda->hdmarx != NULL)
|
||||
{
|
||||
if (hirda->hdmarx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
|
||||
/* Restore hirda->gState and hirda->RxState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
hirda->AbortCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_IRDA_AbortCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA 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.
|
||||
* @param hdma DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
hirda->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (hirda->hdmatx != NULL)
|
||||
{
|
||||
if (hirda->hdmatx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
hirda->TxXferCount = 0x00U;
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
hirda->ErrorCode = HAL_IRDA_ERROR_NONE;
|
||||
|
||||
/* Restore hirda->gState and hirda->RxState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
hirda->AbortCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_IRDA_AbortCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA Tx communication abort callback, when initiated by user by a call to
|
||||
* HAL_IRDA_AbortTransmit_IT API (Abort only Tx transfer)
|
||||
* (This callback is executed at end of DMA Tx Abort procedure following user abort request,
|
||||
* and leads to user Tx Abort Complete callback execution).
|
||||
* @param hdma DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
hirda->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
hirda->AbortTransmitCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_IRDA_AbortTransmitCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA IRDA Rx communication abort callback, when initiated by user by a call to
|
||||
* HAL_IRDA_AbortReceive_IT API (Abort only Rx transfer)
|
||||
* (This callback is executed at end of DMA Rx Abort procedure following user abort request,
|
||||
* and leads to user Rx Abort Complete callback execution).
|
||||
* @param hdma DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
IRDA_HandleTypeDef *hirda = (IRDA_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
hirda->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
hirda->AbortReceiveCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_IRDA_AbortReceiveCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send an amount of data in non blocking mode.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef IRDA_Transmit_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
|
||||
/* Check that a Tx process is ongoing */
|
||||
if (hirda->gState == HAL_IRDA_STATE_BUSY_TX)
|
||||
{
|
||||
if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) hirda->pTxBuffPtr;
|
||||
hirda->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
hirda->pTxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
hirda->pTxBuffPtr += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hirda->Instance->DR = (uint8_t)(*hirda->pTxBuffPtr++ & (uint8_t)0x00FF);
|
||||
}
|
||||
|
||||
if (--hirda->TxXferCount == 0U)
|
||||
{
|
||||
/* Disable the IRDA Transmit Data Register Empty Interrupt */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
/* Enable the IRDA Transmit Complete Interrupt */
|
||||
SET_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wraps up transmission in non blocking mode.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef IRDA_EndTransmit_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
/* Disable the IRDA Transmit Complete Interrupt */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_TCIE);
|
||||
|
||||
/* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Tx process is ended, restore hirda->gState to Ready */
|
||||
hirda->gState = HAL_IRDA_STATE_READY;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx complete callback */
|
||||
hirda->TxCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Tx complete callback */
|
||||
HAL_IRDA_TxCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACK */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in non blocking mode.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef IRDA_Receive_IT(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint16_t uhdata;
|
||||
|
||||
/* Check that a Rx process is ongoing */
|
||||
if (hirda->RxState == HAL_IRDA_STATE_BUSY_RX)
|
||||
{
|
||||
uhdata = (uint16_t) READ_REG(hirda->Instance->DR);
|
||||
if (hirda->Init.WordLength == IRDA_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) hirda->pRxBuffPtr;
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(uhdata & (uint16_t)0x01FF);
|
||||
hirda->pRxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(uhdata & (uint16_t)0x00FF);
|
||||
hirda->pRxBuffPtr += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hirda->Init.Parity == IRDA_PARITY_NONE)
|
||||
{
|
||||
*hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*hirda->pRxBuffPtr++ = (uint8_t)(uhdata & (uint8_t)0x007F);
|
||||
}
|
||||
}
|
||||
|
||||
if (--hirda->RxXferCount == 0U)
|
||||
{
|
||||
/* Disable the IRDA Data Register not empty Interrupt */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_RXNEIE);
|
||||
|
||||
/* Disable the IRDA Parity Error Interrupt */
|
||||
CLEAR_BIT(hirda->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Disable the IRDA Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(hirda->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Rx process is completed, restore hirda->RxState to Ready */
|
||||
hirda->RxState = HAL_IRDA_STATE_READY;
|
||||
|
||||
#if (USE_HAL_IRDA_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx complete callback */
|
||||
hirda->RxCpltCallback(hirda);
|
||||
#else
|
||||
/* Call legacy weak Rx complete callback */
|
||||
HAL_IRDA_RxCpltCallback(hirda);
|
||||
#endif /* USE_HAL_IRDA_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the IRDA peripheral.
|
||||
* @param hirda Pointer to a IRDA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IRDA module.
|
||||
* @retval None
|
||||
*/
|
||||
static void IRDA_SetConfig(IRDA_HandleTypeDef *hirda)
|
||||
{
|
||||
uint32_t pclk;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_IRDA_INSTANCE(hirda->Instance));
|
||||
assert_param(IS_IRDA_BAUDRATE(hirda->Init.BaudRate));
|
||||
assert_param(IS_IRDA_WORD_LENGTH(hirda->Init.WordLength));
|
||||
assert_param(IS_IRDA_PARITY(hirda->Init.Parity));
|
||||
assert_param(IS_IRDA_MODE(hirda->Init.Mode));
|
||||
assert_param(IS_IRDA_POWERMODE(hirda->Init.IrDAMode));
|
||||
|
||||
/*-------------------------- USART CR2 Configuration ------------------------*/
|
||||
/* Clear STOP[13:12] bits */
|
||||
CLEAR_BIT(hirda->Instance->CR2, USART_CR2_STOP);
|
||||
|
||||
/*-------------------------- USART CR1 Configuration -----------------------*/
|
||||
/* Clear M, PCE, PS, TE and RE bits */
|
||||
CLEAR_BIT(hirda->Instance->CR1, (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE));
|
||||
|
||||
/* Configure the USART Word Length, Parity and mode:
|
||||
Set the M bits according to hirda->Init.WordLength value
|
||||
Set PCE and PS bits according to hirda->Init.Parity value
|
||||
Set TE and RE bits according to hirda->Init.Mode value */
|
||||
/* Write to USART CR1 */
|
||||
SET_BIT(hirda->Instance->CR1, (hirda->Init.WordLength | hirda->Init.Parity | hirda->Init.Mode));
|
||||
|
||||
/*-------------------------- USART CR3 Configuration -----------------------*/
|
||||
/* Clear CTSE and RTSE bits */
|
||||
CLEAR_BIT(hirda->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
|
||||
|
||||
/*-------------------------- USART BRR Configuration -----------------------*/
|
||||
if(hirda->Instance == USART1)
|
||||
{
|
||||
pclk = HAL_RCC_GetPCLK2Freq();
|
||||
SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
|
||||
}
|
||||
else
|
||||
{
|
||||
pclk = HAL_RCC_GetPCLK1Freq();
|
||||
SET_BIT(hirda->Instance->BRR, IRDA_BRR(pclk, hirda->Init.BaudRate));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
242
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_iwdg.c
Normal file
242
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_iwdg.c
Normal file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_iwdg.c
|
||||
* @author MCU Application Team
|
||||
* @brief IWDG HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Independent Watchdog (IWDG) peripheral:
|
||||
* + Initialization and Start functions
|
||||
* + IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### IWDG Generic features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) The IWDG can be started by either software or hardware (configurable
|
||||
through option byte).
|
||||
|
||||
(+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even
|
||||
if the main clock fails.
|
||||
|
||||
(+) Once the IWDG is started, the LSI is forced ON and both can not be
|
||||
disabled. The counter starts counting down from the reset value (0xFFF).
|
||||
When it reaches the end of count value (0x000) a reset signal is
|
||||
generated (IWDG reset).
|
||||
|
||||
(+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
|
||||
the IWDG_RLR value is reloaded in the counter and the watchdog reset is
|
||||
prevented.
|
||||
|
||||
(+) The IWDG is implemented in the VDD voltage domain that is still functional
|
||||
in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY).
|
||||
IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
|
||||
reset occurs.
|
||||
|
||||
(+) Debug mode : When the microcontroller enters debug mode (core halted),
|
||||
the IWDG counter either continues to work normally or stops, depending
|
||||
on DBG_IWDG_STOP configuration bit in DBG module, accessible through
|
||||
__HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros
|
||||
|
||||
[..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
|
||||
The IWDG timeout may vary due to LSI frequency dispersion. PY32F0xx
|
||||
devices provide the capability to measure the LSI frequency (LSI clock
|
||||
connected internally to TIM5 CH4 input capture). The measured value
|
||||
can be used to have an IWDG timeout with an acceptable accuracy.
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Use IWDG using HAL_IWDG_Init() function to :
|
||||
(++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
|
||||
clock is forced ON and IWDG counter starts downcounting.
|
||||
(++) Enable write access to configuration register: IWDG_PR & IWDG_RLR.
|
||||
(++) Configure the IWDG prescaler and counter reload value. This reload
|
||||
value will be loaded in the IWDG counter each time the watchdog is
|
||||
reloaded, then the IWDG will start counting down from this value.
|
||||
(++) wait for status flags to be reset"
|
||||
|
||||
(#) Then the application program must refresh the IWDG counter at regular
|
||||
intervals during normal operation to prevent an MCU reset, using
|
||||
HAL_IWDG_Refresh() function.
|
||||
|
||||
*** IWDG HAL driver macros list ***
|
||||
====================================
|
||||
[..]
|
||||
Below the list of most used macros in IWDG HAL driver:
|
||||
(+) __HAL_IWDG_START: Enable the IWDG peripheral
|
||||
(+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
|
||||
the reload register
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
/** @defgroup IWDG IWDG
|
||||
* @brief IWDG HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup IWDG_Private_Defines IWDG Private Defines
|
||||
* @{
|
||||
*/
|
||||
/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
|
||||
higher prescaler (256), and according to HSI variation, we need to wait at
|
||||
least 6 cycles so 48 ms. */
|
||||
#define HAL_IWDG_DEFAULT_TIMEOUT 48U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions_Group1
|
||||
* @brief Initialization and Start functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and Start functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the IWDG according to the specified parameters in the
|
||||
IWDG_InitTypeDef of associated handle.
|
||||
(+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
|
||||
is reloaded in order to exit function with correct time base.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the IWDG according to the specified parameters in the
|
||||
* IWDG_InitTypeDef and start watchdog. Before exiting function,
|
||||
* watchdog is refreshed in order to have correct time base.
|
||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Check the IWDG handle allocation */
|
||||
if (hiwdg == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
|
||||
assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
|
||||
assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
|
||||
|
||||
/* Enable IWDG. LSI requires ready */
|
||||
__HAL_IWDG_START(hiwdg);
|
||||
|
||||
/* Enable write access to IWDG_PR and IWDG_RLR registers by writing 0x5555 in KR */
|
||||
IWDG_ENABLE_WRITE_ACCESS(hiwdg);
|
||||
|
||||
/* Write to IWDG registers the Prescaler & Reload values to work with */
|
||||
hiwdg->Instance->PR = hiwdg->Init.Prescaler;
|
||||
hiwdg->Instance->RLR = hiwdg->Init.Reload;
|
||||
|
||||
/* Check pending flag, if previous update not done, return timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait for register to be updated */
|
||||
while (hiwdg->Instance->SR != RESET)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* Reload IWDG counter with value defined in the reload register */
|
||||
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup IWDG_Exported_Functions_Group2
|
||||
* @brief IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Refresh the IWDG.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Refresh the IWDG.
|
||||
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified IWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
|
||||
{
|
||||
/* Reload IWDG counter with value defined in the reload register */
|
||||
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
251
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_led.c
Normal file
251
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_led.c
Normal file
@@ -0,0 +1,251 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_led.c
|
||||
* @author MCU Application Team
|
||||
* @brief LED HAL module driver.
|
||||
******************************************************************************
|
||||
* @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"
|
||||
|
||||
#ifdef HAL_LED_MODULE_ENABLED
|
||||
static void LED_SetConfig(LED_HandleTypeDef *hled);
|
||||
|
||||
/**
|
||||
* @brief Initializes the LED according to the specified parameters
|
||||
* in the LED_InitTypeDef and initialize the associated handle.
|
||||
* @param hled Pointer to a LED_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified LED.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LED_Init(LED_HandleTypeDef *hled)
|
||||
{
|
||||
/* Check the LED handle allocation */
|
||||
if (hled == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LED_ALL_INSTANCE(hled->Instance));
|
||||
assert_param(IS_LED_COM_DRIVE(hled->Init.ComDrive));
|
||||
assert_param(IS_LED_PRISCALER(hled->Init.Prescaler));
|
||||
assert_param(IS_LED_COM_NUM(hled->Init.ComNum));
|
||||
assert_param(IS_LED_LIGHT_TIME(hled->Init.LightTime));
|
||||
assert_param(IS_LED_DEAD_TIME(hled->Init.DeadTime));
|
||||
|
||||
if (hled->State == HAL_LED_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
__HAL_UNLOCK(hled);
|
||||
|
||||
#if (USE_HAL_LED_REGISTER_CALLBACKS == 1)
|
||||
/* Reset Callback pointers */
|
||||
if (hled->EwiCallback == NULL)
|
||||
{
|
||||
hled->EwiCallback = HAL_LED_LightCpltCallback;
|
||||
}
|
||||
|
||||
if (hled->MspInitCallback == NULL)
|
||||
{
|
||||
hled->MspInitCallback = HAL_LED_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
hled->MspInitCallback(hwwdg);
|
||||
#else
|
||||
HAL_LED_MspInit(hled);
|
||||
#endif
|
||||
}
|
||||
|
||||
hled->State = HAL_LED_STATE_BUSY;
|
||||
|
||||
/* LED Register config */
|
||||
LED_SetConfig(hled);
|
||||
|
||||
/* Enable the peripheral */
|
||||
__HAL_LED_ENABLE(hled);
|
||||
|
||||
/* Initialize the LED state */
|
||||
hled->State= HAL_LED_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief De-initializes the LED peripheral registers to their default reset values.
|
||||
* @param hled Pointer to a LED_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified LED.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LED_DeInit(LED_HandleTypeDef *hled)
|
||||
{
|
||||
if (hled == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LED_ALL_INSTANCE(hled->Instance));
|
||||
|
||||
hled->Instance->CR = 0x00;
|
||||
hled->Instance->PR = 0x00;
|
||||
hled->Instance->DR0 = 0x00;
|
||||
hled->Instance->DR1 = 0x00;
|
||||
hled->Instance->DR2 = 0x00;
|
||||
hled->Instance->DR3 = 0x00;
|
||||
hled->Instance->IR = 0x01;
|
||||
|
||||
hled->State = HAL_LED_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hled);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the specified COM display value
|
||||
* @param hled Pointer to a LED_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified LED..
|
||||
* comCh Specify COM channels.
|
||||
* @arg @ref LED_COM0
|
||||
* @arg @ref LED_COM1
|
||||
* @arg @ref LED_COM2
|
||||
* @arg @ref LED_COM3
|
||||
* @arg @ref LED_COM_ALL
|
||||
* data Specify display values
|
||||
* @arg @ref LED_DISP_0 display value 0
|
||||
* @arg @ref LED_DISP_1 display value 1
|
||||
* @arg @ref LED_DISP_2 display value 2
|
||||
* @arg @ref LED_DISP_3 display value 3
|
||||
* @arg @ref LED_DISP_4 display value 4
|
||||
* @arg @ref LED_DISP_5 display value 5
|
||||
* @arg @ref LED_DISP_6 display value 6
|
||||
* @arg @ref LED_DISP_7 display value 7
|
||||
* @arg @ref LED_DISP_8 display value 8
|
||||
* @arg @ref LED_DISP_9 display value 9
|
||||
* @arg @ref LED_DISP_A display character A
|
||||
* @arg @ref LED_DISP_B display character B
|
||||
* @arg @ref LED_DISP_C display character C
|
||||
* @arg @ref LED_DISP_D display character D
|
||||
* @arg @ref LED_DISP_E display character E
|
||||
* @arg @ref LED_DISP_F display character F
|
||||
* @arg @ref LED_DISP_H display character H
|
||||
* @arg @ref LED_DISP_P display character P
|
||||
* @arg @ref LED_DISP_U display character U
|
||||
* @arg @ref LED_DISP_DOT display .
|
||||
* @arg @ref LED_DISP_FULL display 8.
|
||||
* @arg @ref LED_DISP_NONE display nothing
|
||||
* @retval State
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LED_SetComDisplay(LED_HandleTypeDef *hled, uint8_t comCh, uint8_t data)
|
||||
{
|
||||
uint32_t position=0x00U;
|
||||
uint32_t chcurrent = 0x00U;
|
||||
uint32_t *pTmp;
|
||||
|
||||
if (hled->State == HAL_LED_STATE_READY)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hled);
|
||||
hled->State = HAL_LED_STATE_BUSY;
|
||||
|
||||
while ((comCh >> position) != 0)
|
||||
{
|
||||
/* Get the COM channel position */
|
||||
chcurrent = comCh & (1U << position);
|
||||
|
||||
if(chcurrent)
|
||||
{
|
||||
pTmp = ((uint32_t *)&hled->Instance->DR0) + position;
|
||||
WRITE_REG(*pTmp, data);
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hled);
|
||||
hled->State = HAL_LED_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LED Register config
|
||||
* @param hled Pointer to a LED_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified LED..
|
||||
* @retval State
|
||||
*/
|
||||
static void LED_SetConfig(LED_HandleTypeDef *hled)
|
||||
{
|
||||
uint32_t tmpreg;
|
||||
|
||||
tmpreg=hled->Init.ComDrive | (hled->Init.ComNum << LED_CR_LED_COM_SEL_Pos);
|
||||
MODIFY_REG(hled->Instance->CR,
|
||||
(uint32_t)(LED_CR_LED_COM_SEL | LED_CR_EHS),
|
||||
tmpreg);
|
||||
WRITE_REG(hled->Instance->PR, hled->Init.Prescaler);
|
||||
WRITE_REG(hled->Instance->TR, (hled->Init.LightTime | (hled->Init.DeadTime<<LED_TR_T2_Pos)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle LED interrupt request.
|
||||
* @param hled LED handle.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_LED_IRQHandler(LED_HandleTypeDef *hled)
|
||||
{
|
||||
/* LED interrupt occurred -------------------------------------*/
|
||||
if (((hled->Instance->IR & LED_IR_FLAG) != 0U) && ((hled->Instance->CR & LED_CR_IE) != 0U))
|
||||
{
|
||||
__HAL_LED_CLEAR_FLAG(hled, LED_IR_FLAG);
|
||||
|
||||
HAL_LED_LightCpltCallback(hled);
|
||||
}
|
||||
}
|
||||
|
||||
__weak void HAL_LED_MspInit(LED_HandleTypeDef *hled)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hled);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_LED_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
__weak void HAL_LED_LightCpltCallback(LED_HandleTypeDef *hled)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hled);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_LED_LightCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#endif /* HAL_LED_MODULE_ENABLED */
|
||||
|
||||
786
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_lptim.c
Normal file
786
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_lptim.c
Normal file
@@ -0,0 +1,786 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_lptim.c
|
||||
* @author MCU Application Team
|
||||
* @brief LPTIM HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Low Power Timer (LPTIM) peripheral:
|
||||
* + Initialization and de-initialization functions.
|
||||
* + Start/Stop operation functions in polling mode.
|
||||
* + Start/Stop operation functions in interrupt mode.
|
||||
* + Reading operation functions.
|
||||
* + Peripheral State functions.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The LPTIM HAL driver can be used as follows:
|
||||
|
||||
(#)Initialize the LPTIM low level resources by implementing the
|
||||
HAL_LPTIM_MspInit():
|
||||
(++) Enable the LPTIM interface clock using __HAL_RCC_LPTIMx_CLK_ENABLE().
|
||||
(++) In case of using interrupts (e.g. HAL_LPTIM_PWM_Start_IT()):
|
||||
(+++) Configure the LPTIM interrupt priority using HAL_NVIC_SetPriority().
|
||||
(+++) Enable the LPTIM IRQ handler using HAL_NVIC_EnableIRQ().
|
||||
(+++) In LPTIM IRQ handler, call HAL_LPTIM_IRQHandler().
|
||||
|
||||
(#)Initialize the LPTIM HAL using HAL_LPTIM_Init(). This function
|
||||
configures mainly:
|
||||
(++) The instance: LPTIM1 or LPTIM2.
|
||||
(++) Clock: the counter clock.
|
||||
(+++) Source : it can be either the ULPTIM input (IN1) or one of
|
||||
the internal clock; (APB, LSE, LSI or HSI).
|
||||
(+++) Prescaler: select the clock divider.
|
||||
(#)Six modes are available:
|
||||
|
||||
(++) PWM Mode: To generate a PWM signal with specified period and pulse,
|
||||
call HAL_LPTIM_PWM_Start() or HAL_LPTIM_PWM_Start_IT() for interruption
|
||||
mode.
|
||||
|
||||
(++) One Pulse Mode: To generate pulse with specified width in response
|
||||
to a stimulus, call HAL_LPTIM_OnePulse_Start() or
|
||||
HAL_LPTIM_OnePulse_Start_IT() for interruption mode.
|
||||
|
||||
(++) Set once Mode: In this mode, the output changes the level (from
|
||||
low level to high level if the output polarity is configured high, else
|
||||
the opposite) when a compare match occurs. To start this mode, call
|
||||
HAL_LPTIM_SetOnce_Start() or HAL_LPTIM_SetOnce_Start_IT() for
|
||||
interruption mode.
|
||||
|
||||
(++) Encoder Mode: To use the encoder interface call
|
||||
HAL_LPTIM_Encoder_Start() or HAL_LPTIM_Encoder_Start_IT() for
|
||||
interruption mode. Only available for LPTIM1 instance.
|
||||
|
||||
(++) Time out Mode: an active edge on one selected trigger input rests
|
||||
the counter. The first trigger event will start the timer, any
|
||||
successive trigger event will reset the counter and the timer will
|
||||
restart. To start this mode call HAL_LPTIM_TimeOut_Start_IT() or
|
||||
HAL_LPTIM_TimeOut_Start_IT() for interruption mode.
|
||||
|
||||
(++) Counter Mode: counter can be used to count external events on
|
||||
the LPTIM Input1 or it can be used to count internal clock cycles.
|
||||
To start this mode, call HAL_LPTIM_Counter_Start() or
|
||||
HAL_LPTIM_Counter_Start_IT() for interruption mode.
|
||||
|
||||
|
||||
(#) User can stop any process by calling the corresponding API:
|
||||
HAL_LPTIM_Xxx_Stop() or HAL_LPTIM_Xxx_Stop_IT() if the process is
|
||||
already started in interruption mode.
|
||||
|
||||
(#) De-initialize the LPTIM peripheral using HAL_LPTIM_DeInit().
|
||||
|
||||
*** Callback registration ***
|
||||
=============================================
|
||||
[..]
|
||||
The compilation define USE_HAL_LPTIM_REGISTER_CALLBACKS when set to 1
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
[..]
|
||||
Use Function @ref HAL_LPTIM_RegisterCallback() to register a callback.
|
||||
@ref HAL_LPTIM_RegisterCallback() takes as parameters the HAL peripheral handle,
|
||||
the Callback ID and a pointer to the user callback function.
|
||||
[..]
|
||||
Use function @ref HAL_LPTIM_UnRegisterCallback() to reset a callback to the
|
||||
default weak function.
|
||||
@ref HAL_LPTIM_UnRegisterCallback takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
[..]
|
||||
These functions allow to register/unregister following callbacks:
|
||||
|
||||
(+) MspInitCallback : LPTIM Base Msp Init Callback.
|
||||
(+) MspDeInitCallback : LPTIM Base Msp DeInit Callback.
|
||||
(+) CompareMatchCallback : Compare match Callback.
|
||||
(+) AutoReloadMatchCallback : Auto-reload match Callback.
|
||||
(+) TriggerCallback : External trigger event detection Callback.
|
||||
(+) CompareWriteCallback : Compare register write complete Callback.
|
||||
(+) AutoReloadWriteCallback : Auto-reload register write complete Callback.
|
||||
(+) DirectionUpCallback : Up-counting direction change Callback.
|
||||
(+) DirectionDownCallback : Down-counting direction change Callback.
|
||||
|
||||
[..]
|
||||
By default, after the Init and when the state is HAL_LPTIM_STATE_RESET
|
||||
all interrupt callbacks are set to the corresponding weak functions:
|
||||
examples @ref HAL_LPTIM_TriggerCallback(), @ref HAL_LPTIM_CompareMatchCallback().
|
||||
|
||||
[..]
|
||||
Exception done for MspInit and MspDeInit functions that are reset to the legacy weak
|
||||
functionalities in the Init/DeInit only when these callbacks are null
|
||||
(not registered beforehand). If not, MspInit or MspDeInit are not null, the Init/DeInit
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
|
||||
|
||||
[..]
|
||||
Callbacks can be registered/unregistered in HAL_LPTIM_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit that can be registered/unregistered
|
||||
in HAL_LPTIM_STATE_READY or HAL_LPTIM_STATE_RESET state,
|
||||
thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
|
||||
In that case first register the MspInit/MspDeInit user callbacks
|
||||
using @ref HAL_LPTIM_RegisterCallback() before calling DeInit or Init function.
|
||||
|
||||
[..]
|
||||
When The compilation define USE_HAL_LPTIM_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available and all callbacks
|
||||
are set to the corresponding weak functions.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 LPTIM LPTIM
|
||||
* @brief LPTIM HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_LPTIM_MODULE_ENABLED
|
||||
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
static void LPTIM_ResetCallback(LPTIM_HandleTypeDef *lptim);
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup LPTIM_Exported_Functions LPTIM Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup LPTIM_Exported_Functions_Group1 Initialization/de-initialization functions
|
||||
* @brief Initialization and Configuration functions.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
==============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the LPTIM according to the specified parameters in the
|
||||
LPTIM_InitTypeDef and initialize the associated handle.
|
||||
(+) DeInitialize the LPTIM peripheral.
|
||||
(+) Initialize the LPTIM MSP.
|
||||
(+) DeInitialize the LPTIM MSP.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the LPTIM according to the specified parameters in the
|
||||
* LPTIM_InitTypeDef and initialize the associated handle.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_Init(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
uint32_t tmpcfgr;
|
||||
|
||||
/* Check the LPTIM handle allocation */
|
||||
if(hlptim == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
|
||||
assert_param(IS_LPTIM_CLOCK_PRESCALER(hlptim->Init.Prescaler));
|
||||
|
||||
if(hlptim->State == HAL_LPTIM_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hlptim->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
/* Reset interrupt callbacks to legacy weak callbacks */
|
||||
LPTIM_ResetCallback(hlptim);
|
||||
|
||||
if(hlptim->MspInitCallback == NULL)
|
||||
{
|
||||
hlptim->MspInitCallback = HAL_LPTIM_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC */
|
||||
hlptim->MspInitCallback(hlptim);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC */
|
||||
HAL_LPTIM_MspInit(hlptim);
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Change the LPTIM state */
|
||||
hlptim->State = HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Get the LPTIMx CFGR value */
|
||||
tmpcfgr = hlptim->Instance->CFGR;
|
||||
|
||||
/* Clear PRESC, PRELOAD */
|
||||
tmpcfgr &= (uint32_t)(~(LPTIM_CFGR_PRELOAD | LPTIM_CFGR_PRESC));
|
||||
|
||||
/* Set initialization parameters */
|
||||
tmpcfgr |= (hlptim->Init.Prescaler|hlptim->Init.UpdateMode);
|
||||
|
||||
/* Write to LPTIMx CFGR */
|
||||
hlptim->Instance->CFGR = tmpcfgr;
|
||||
|
||||
/* Change the LPTIM state */
|
||||
hlptim->State = HAL_LPTIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the LPTIM peripheral.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_DeInit(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Check the LPTIM handle allocation */
|
||||
if(hlptim == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Change the LPTIM state */
|
||||
hlptim->State = HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Disable the LPTIM Peripheral Clock */
|
||||
__HAL_LPTIM_DISABLE(hlptim);
|
||||
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
if(hlptim->MspDeInitCallback == NULL)
|
||||
{
|
||||
hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit;
|
||||
}
|
||||
|
||||
/* DeInit the low level hardware: CLOCK, NVIC.*/
|
||||
hlptim->MspDeInitCallback(hlptim);
|
||||
#else
|
||||
/* DeInit the low level hardware: CLOCK, NVIC.*/
|
||||
HAL_LPTIM_MspDeInit(hlptim);
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
|
||||
/* Change the LPTIM state */
|
||||
hlptim->State = HAL_LPTIM_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hlptim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the LPTIM MSP.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hlptim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_LPTIM_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize LPTIM MSP.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_LPTIM_MspDeInit(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hlptim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_LPTIM_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Start the LPTIM in Set once mode.
|
||||
* @param hlptim LPTIM handle
|
||||
* @param Period Specifies the Autoreload value.
|
||||
* This parameter must be a value between 0x0000 and 0xFFFF.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start(LPTIM_HandleTypeDef *hlptim, uint32_t Period)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
assert_param(IS_LPTIM_PERIOD(Period));
|
||||
|
||||
/* Set the LPTIM state */
|
||||
hlptim->State= HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_LPTIM_ENABLE(hlptim);
|
||||
|
||||
/* Load the period value in the autoreload register */
|
||||
__HAL_LPTIM_AUTORELOAD_SET(hlptim, Period);
|
||||
|
||||
/* Start timer in single mode */
|
||||
__HAL_LPTIM_START_SINGLE(hlptim);
|
||||
|
||||
/* Change the TIM state*/
|
||||
hlptim->State= HAL_LPTIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the LPTIM Set once mode.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
|
||||
/* Set the LPTIM state */
|
||||
hlptim->State= HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_LPTIM_DISABLE(hlptim);
|
||||
|
||||
/* Change the TIM state*/
|
||||
hlptim->State= HAL_LPTIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the LPTIM Set once mode in interrupt mode.
|
||||
* @param hlptim LPTIM handle
|
||||
* @param Period Specifies the Autoreload value.
|
||||
* This parameter must be a value between 0x0000 and 0xFFFF.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_SetOnce_Start_IT(LPTIM_HandleTypeDef *hlptim, uint32_t Period)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
assert_param(IS_LPTIM_PERIOD(Period));
|
||||
|
||||
/* Set the LPTIM state */
|
||||
hlptim->State= HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Enable Autoreload match interrupt */
|
||||
__HAL_LPTIM_ENABLE_IT(hlptim, LPTIM_IT_ARRM);
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_LPTIM_ENABLE(hlptim);
|
||||
|
||||
/* Load the period value in the autoreload register */
|
||||
__HAL_LPTIM_AUTORELOAD_SET(hlptim, Period);
|
||||
|
||||
/* Start timer in single mode */
|
||||
__HAL_LPTIM_START_SINGLE(hlptim);
|
||||
|
||||
/* Change the TIM state*/
|
||||
hlptim->State= HAL_LPTIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the LPTIM Set once mode in interrupt mode.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_SetOnce_Stop_IT(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
|
||||
/* Set the LPTIM state */
|
||||
hlptim->State= HAL_LPTIM_STATE_BUSY;
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_LPTIM_DISABLE(hlptim);
|
||||
|
||||
/* Disable Autoreload match interrupt */
|
||||
__HAL_LPTIM_DISABLE_IT(hlptim, LPTIM_IT_ARRM);
|
||||
|
||||
/* Change the TIM state*/
|
||||
hlptim->State= HAL_LPTIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup LPTIM_Exported_Functions_Group3 LPTIM Read operation functions
|
||||
* @brief Read operation functions.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### LPTIM Read operation functions #####
|
||||
==============================================================================
|
||||
[..] This section provides LPTIM Reading functions.
|
||||
(+) Read the counter value.
|
||||
(+) Read the period (Auto-reload) value.
|
||||
(+) Read the pulse (Compare)value.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the current counter value.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval Counter value.
|
||||
*/
|
||||
uint32_t HAL_LPTIM_ReadCounter(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
|
||||
return (hlptim->Instance->CNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the current Autoreload (Period) value.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval Autoreload value.
|
||||
*/
|
||||
uint32_t HAL_LPTIM_ReadAutoReload(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
|
||||
|
||||
return (hlptim->Instance->ARR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/** @defgroup LPTIM_Exported_Functions_Group4 LPTIM IRQ handler and callbacks
|
||||
* @brief LPTIM IRQ handler.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### LPTIM IRQ handler and callbacks #####
|
||||
==============================================================================
|
||||
[..] This section provides LPTIM IRQ handler and callback functions called within
|
||||
the IRQ handler:
|
||||
(+) LPTIM interrupt request handler
|
||||
(+) Compare match Callback
|
||||
(+) Auto-reload match Callback
|
||||
(+) External trigger event detection Callback
|
||||
(+) Compare register write complete Callback
|
||||
(+) Auto-reload register write complete Callback
|
||||
(+) Up-counting direction change Callback
|
||||
(+) Down-counting direction change Callback
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Handle LPTIM interrupt request.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_LPTIM_IRQHandler(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Autoreload match interrupt */
|
||||
if(__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARRM) != RESET)
|
||||
{
|
||||
if(__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARRM) != RESET)
|
||||
{
|
||||
/* Clear Autoreload match flag */
|
||||
__HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARRM);
|
||||
|
||||
/* Autoreload match Callback */
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
hlptim->AutoReloadMatchCallback(hlptim);
|
||||
#else
|
||||
HAL_LPTIM_AutoReloadMatchCallback(hlptim);
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Autoreload match callback in non-blocking mode.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_LPTIM_AutoReloadMatchCallback(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hlptim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_LPTIM_AutoReloadMatchCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User LPTIM callback to be used instead of the weak predefined callback
|
||||
* @param hlptim LPTIM handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_LPTIM_MSPINIT_CB_ID LPTIM Base Msp Init Callback ID
|
||||
* @arg @ref HAL_LPTIM_MSPDEINIT_CB_ID LPTIM Base Msp DeInit Callback ID
|
||||
* @arg @ref HAL_LPTIM_AUTORELOAD_MATCH_CB_ID Auto-reload match Callback ID
|
||||
* @param pCallback pointer to the callback function
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_RegisterCallback(LPTIM_HandleTypeDef * hlptim,
|
||||
HAL_LPTIM_CallbackIDTypeDef CallbackID,
|
||||
pLPTIM_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if(pCallback == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hlptim);
|
||||
|
||||
if(hlptim->State == HAL_LPTIM_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_LPTIM_MSPINIT_CB_ID :
|
||||
hlptim->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_MSPDEINIT_CB_ID :
|
||||
hlptim->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_AUTORELOAD_MATCH_CB_ID :
|
||||
hlptim->AutoReloadMatchCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(hlptim->State == HAL_LPTIM_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_LPTIM_MSPINIT_CB_ID :
|
||||
hlptim->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_MSPDEINIT_CB_ID :
|
||||
hlptim->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hlptim);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a LPTIM callback
|
||||
* LLPTIM callback is redirected to the weak predefined callback
|
||||
* @param hlptim LPTIM handle
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_LPTIM_MSPINIT_CB_ID LPTIM Base Msp Init Callback ID
|
||||
* @arg @ref HAL_LPTIM_MSPDEINIT_CB_ID LPTIM Base Msp DeInit Callback ID
|
||||
* @arg @ref HAL_LPTIM_AUTORELOAD_MATCH_CB_ID Auto-reload match Callback ID
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_LPTIM_UnRegisterCallback(LPTIM_HandleTypeDef * hlptim,
|
||||
HAL_LPTIM_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hlptim);
|
||||
|
||||
if(hlptim->State == HAL_LPTIM_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_LPTIM_MSPINIT_CB_ID :
|
||||
hlptim->MspInitCallback = HAL_LPTIM_MspInit; /* Legacy weak MspInit Callback */
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_MSPDEINIT_CB_ID :
|
||||
hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit; /* Legacy weak Msp DeInit Callback */
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_AUTORELOAD_MATCH_CB_ID :
|
||||
hlptim->AutoReloadMatchCallback = HAL_LPTIM_AutoReloadMatchCallback; /* Legacy weak IC Msp DeInit Callback */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(hlptim->State == HAL_LPTIM_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_LPTIM_MSPINIT_CB_ID :
|
||||
hlptim->MspInitCallback = HAL_LPTIM_MspInit; /* Legacy weak MspInit Callback */
|
||||
break;
|
||||
|
||||
case HAL_LPTIM_MSPDEINIT_CB_ID :
|
||||
hlptim->MspDeInitCallback = HAL_LPTIM_MspDeInit; /* Legacy weak Msp DeInit Callback */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hlptim);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup LPTIM_Group5 Peripheral State functions
|
||||
* @brief Peripheral State functions.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral State functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection permits to get in run-time the status of the peripheral.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the LPTIM handle state.
|
||||
* @param hlptim LPTIM handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_LPTIM_StateTypeDef HAL_LPTIM_GetState(LPTIM_HandleTypeDef *hlptim)
|
||||
{
|
||||
/* Return LPTIM handle state */
|
||||
return hlptim->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup LPTIM_Private_Functions LPTIM Private Functions
|
||||
* @{
|
||||
*/
|
||||
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Reset interrupt callbacks to the legacy weak callbacks.
|
||||
* @param lptim pointer to a LPTIM_HandleTypeDef structure that contains
|
||||
* the configuration information for LPTIM module.
|
||||
* @retval None
|
||||
*/
|
||||
static void LPTIM_ResetCallback(LPTIM_HandleTypeDef *lptim)
|
||||
{
|
||||
/* Reset the LPTIM callback to the legacy weak callbacks */
|
||||
lptim->AutoReloadMatchCallback = HAL_LPTIM_AutoReloadMatchCallback; /* Auto-reload match Callback */
|
||||
}
|
||||
#endif /* USE_HAL_LPTIM_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#endif /* HAL_LPTIM_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
529
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_pwr.c
Normal file
529
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_pwr.c
Normal file
@@ -0,0 +1,529 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_pwr.c
|
||||
* @author MCU Application Team
|
||||
* @brief PWR HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Power Controller (PWR) peripheral:
|
||||
* + Initialization/de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup PWR_Private_Defines PWR Private Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(PWR_PVD_SUPPORT)
|
||||
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
|
||||
* @{
|
||||
*/
|
||||
#define PVD_MODE_IT 0x00010000U /*!< Mask for interruption yielded
|
||||
by PVD threshold crossing */
|
||||
#define PVD_MODE_EVT 0x00020000U /*!< Mask for event yielded
|
||||
by PVD threshold crossing */
|
||||
#define PVD_RISING_EDGE 0x00000001U /*!< Mask for rising edge set as
|
||||
PVD trigger */
|
||||
#define PVD_FALLING_EDGE 0x00000002U /*!< Mask for falling edge set as
|
||||
PVD trigger */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup PWR_Exported_Functions PWR Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and de-initialization functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the HAL PWR peripheral registers to their default reset
|
||||
values.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DeInit(void)
|
||||
{
|
||||
__HAL_RCC_PWR_FORCE_RESET();
|
||||
__HAL_RCC_PWR_RELEASE_RESET();
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief Low Power modes configuration functions
|
||||
*
|
||||
@verbatim
|
||||
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
|
||||
[..]
|
||||
*** PVD configuration ***
|
||||
=========================
|
||||
[..]
|
||||
(+) The PVD is used to monitor the VDD power supply by comparing it to a
|
||||
threshold selected by the PVD Level (PVDT[2:0]bits in PWR CR2 register).
|
||||
(+) PVDO flag is available to indicate if VDD/VDDA is higher or lower
|
||||
than the PVD threshold. This event is internally connected to the EXTI
|
||||
line 16 and can generate an interrupt if enabled.
|
||||
(+) The PVD is stopped in Standby mode.
|
||||
|
||||
*** WakeUp pin configuration ***
|
||||
================================
|
||||
[..]
|
||||
(+) WakeUp pins are used to wakeup the system from Standby mode or
|
||||
Shutdown mode. WakeUp pins polarity can be set to configure event
|
||||
detection on high level (rising edge) or low level (falling edge).
|
||||
|
||||
*** Low Power mode configuration ***
|
||||
=====================================
|
||||
[..]
|
||||
The devices feature 7 low-power modes:
|
||||
(+) Low-power run mode: core and peripherals are running at low frequency.
|
||||
Regulator is in low power mode.
|
||||
(+) Sleep mode: Cortex-M0+ core stopped, peripherals kept running,
|
||||
regulator is main mode.
|
||||
(+) Low-power Sleep mode: Cortex-M0+ core stopped, peripherals kept running
|
||||
and regulator in low power mode.
|
||||
(+) Stop 0 mode: all clocks are stopped except LSI and LSE, regulator is
|
||||
main mode.
|
||||
(+) Stop 1 mode: all clocks are stopped except LSI and LSE, main regulator
|
||||
off, low power regulator on.
|
||||
|
||||
*** Low-power run mode ***
|
||||
==========================
|
||||
[..]
|
||||
(+) Entry: (from main run mode)
|
||||
(++) set LPR bit with HAL_PWREx_EnableLowPowerRunMode() API after
|
||||
having decreased the system clock below 2 MHz.
|
||||
(+) Exit:
|
||||
(++) clear LPR bit then wait for REGLPF bit to be reset with
|
||||
HAL_PWREx_DisableLowPowerRunMode() API. Only then can the
|
||||
system clock frequency be increased above 2 MHz.
|
||||
|
||||
*** Sleep mode / Low-power sleep mode ***
|
||||
=========================================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Sleep & Low-power Sleep modes are entered through
|
||||
HAL_PWR_EnterSLEEPMode() API specifying whether or not the regulator
|
||||
is forced to low-power mode and if exit is interrupt or event
|
||||
triggered.
|
||||
(++) PWR_MAINREGULATOR_ON: Sleep mode (regulator in main mode).
|
||||
(++) PWR_LOWPOWERREGULATOR_ON: Low-power Sleep mode (regulator in low
|
||||
power mode). In this case, the system clock frequency must have
|
||||
been decreased below 2 MHz beforehand.
|
||||
(++) PWR_SLEEPENTRY_WFI: Core enters sleep mode with WFI instruction
|
||||
(++) PWR_SLEEPENTRY_WFE: Core enters sleep mode with WFE instruction
|
||||
(+) WFI Exit:
|
||||
(++) Any interrupt enabled in nested vectored interrupt controller (NVIC)
|
||||
(+) WFE Exit:
|
||||
(++) Any wakeup event if cortex is configured with SEVONPEND = 0
|
||||
(++) Interrupt even when disabled in NVIC if cortex is configured with
|
||||
SEVONPEND = 1
|
||||
[..] When exiting the Low-power Sleep mode by issuing an interrupt or a wakeup event,
|
||||
the MCU is in Low-power Run mode.
|
||||
|
||||
*** Stop 0 & Stop 1 modes ***
|
||||
=============================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Stop modes are entered through the following APIs:
|
||||
(++) HAL_PWR_EnterSTOPMode() with following settings:
|
||||
(+++) PWR_MAINREGULATOR_ON to enter STOP0 mode.
|
||||
(+++) PWR_LOWPOWERREGULATOR_ON to enter STOP1 mode.
|
||||
(+) Exit (interrupt or event-triggered, specified when entering STOP mode):
|
||||
(++) PWR_STOPENTRY_WFI: enter Stop mode with WFI instruction
|
||||
(++) PWR_STOPENTRY_WFE: enter Stop mode with WFE instruction
|
||||
(+) WFI Exit:
|
||||
(++) Any EXTI line (internal or external) configured in interrupt mode
|
||||
with corresponding interrupt enable in NVIC
|
||||
(+) WFE Exit:
|
||||
(++) Any EXTI line (internal or external) configured in event mode if
|
||||
cortex is configured with SEVONPEND = 0
|
||||
(++) Any EXTI line configured in interrupt mode (even if the
|
||||
corresponding EXTI Interrupt vector is disabled in the NVIC) if
|
||||
cortex is configured with SEVONPEND = 0. The interrupt source can
|
||||
be external interrupts or peripherals with wakeup capability.
|
||||
[..] When exiting Stop, the MCU is either in Run mode or in Low-power Run mode
|
||||
depending on the LPR bit setting.
|
||||
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable access to the backup domain
|
||||
* (RTC & TAMP registers, backup registers, RCC BDCR register).
|
||||
* @note After reset, the backup domain is protected against
|
||||
* possible unwanted write accesses. All RTC & TAMP registers (backup
|
||||
* registers included) and RCC BDCR register are concerned.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableBkUpAccess(void)
|
||||
{
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable access to the backup domain
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableBkUpAccess(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
}
|
||||
|
||||
|
||||
#if defined(PWR_PVD_SUPPORT)
|
||||
/**
|
||||
* @brief Configure the Power Voltage Detector (PVD).
|
||||
* @param sConfigPVD pointer to a PWR_PVDTypeDef structure that contains the
|
||||
PVD configuration information: threshold levels, operating mode.
|
||||
* @note Refer to the electrical characteristics of your device datasheet for
|
||||
* more details about the voltage thresholds corresponding to each
|
||||
* detection level.
|
||||
* @note User should take care that rising threshold is higher than falling
|
||||
* one in order to avoid having always PVDO output set.
|
||||
* @retval HAL_OK
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
|
||||
assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
|
||||
|
||||
/* Set PVD level bits only according to PVDLevel value */
|
||||
MODIFY_REG(PWR->CR2, (PWR_CR2_PVDT | PWR_CR2_FLTEN | PWR_CR2_FLT_TIME | PWR_CR2_SRCSEL), \
|
||||
(sConfigPVD->PVDLevel | sConfigPVD->PVDFilter | sConfigPVD->PVDSource));
|
||||
|
||||
/* Clear any previous config, in case no event or IT mode is selected */
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the Power Voltage Detector (PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnablePVD(void)
|
||||
{
|
||||
SET_BIT(PWR->CR2, PWR_CR2_PVDE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable the Power Voltage Detector (PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisablePVD(void)
|
||||
{
|
||||
CLEAR_BIT(PWR->CR2, PWR_CR2_PVDE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Sleep or Low-power Sleep mode.
|
||||
* @note In Sleep/Low-power Sleep mode, all I/O pins keep the same state as
|
||||
* in Run mode.
|
||||
* @param SLEEPEntry Specifies if Sleep mode is entered with WFI or WFE
|
||||
* instruction. This parameter can be one of the following values:
|
||||
* @arg @ref PWR_SLEEPENTRY_WFI enter Sleep or Low-power Sleep
|
||||
* mode with WFI instruction
|
||||
* @arg @ref PWR_SLEEPENTRY_WFE enter Sleep or Low-power Sleep
|
||||
* mode with WFE instruction
|
||||
* @note When WFI entry is used, tick interrupt have to be disabled if not
|
||||
* desired as the interrupt wake up source.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSLEEPMode(uint8_t SLEEPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_SLEEP_ENTRY(SLEEPEntry));
|
||||
|
||||
/* Clear SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
/* Select SLEEP mode entry -------------------------------------------------*/
|
||||
if(SLEEPEntry == PWR_SLEEPENTRY_WFI)
|
||||
{
|
||||
/* Request Wait For Interrupt */
|
||||
__WFI();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Request Wait For Event */
|
||||
__SEV();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enter Stop mode
|
||||
* @note This API is named HAL_PWR_EnterSTOPMode to ensure compatibility with
|
||||
* legacy code running on devices where only "Stop mode" is mentioned
|
||||
* with main or low power regulator ON.
|
||||
* @note In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note All clocks in the VCORE domain are stopped; the PLL, the HSI and the
|
||||
* HSE oscillators are disabled. Some peripherals with the wakeup
|
||||
* capability can switch on the HSI to receive a frame, and switch off
|
||||
* the HSI after receiving the frame if it is not a wakeup frame.
|
||||
* SRAM and register contents are preserved.
|
||||
* The BOR is available.
|
||||
* The voltage regulator can be configured either in normal (Stop 0) or
|
||||
* low-power mode (Stop 1).
|
||||
* @note When exiting Stop 0 or Stop 1 mode by issuing an interrupt or a
|
||||
* wakeup event, the HSI RC oscillator is selected as system clock
|
||||
* @note When the voltage regulator operates in low power mode (Stop 1),
|
||||
* an additional startup delay is incurred when waking up. By keeping
|
||||
* the internal regulator ON during Stop mode (Stop 0), the consumption
|
||||
* is higher although the startup time is reduced.
|
||||
* @param Regulator Specifies the regulator state in Stop mode
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref PWR_MAINREGULATOR_ON Stop 0 mode (main regulator ON)
|
||||
* @arg @ref PWR_LOWPOWERREGULATOR_ON Stop 1 mode (low power
|
||||
* regulator ON)
|
||||
* @param STOPEntry Specifies Stop 0 or Stop 1 mode is entered with WFI or
|
||||
* WFE instruction. This parameter can be one of the following values:
|
||||
* @arg @ref PWR_STOPENTRY_WFI Enter Stop 0 or Stop 1 mode with WFI
|
||||
* instruction.
|
||||
* @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 or Stop 1 mode with WFE
|
||||
* instruction.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_REGULATOR(Regulator));
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
if (Regulator != PWR_MAINREGULATOR_ON)
|
||||
{
|
||||
/* Stop mode with Low-Power Regulator */
|
||||
SET_BIT(PWR->CR1,PWR_CR1_LPR);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Stop mode with Main Regulator */
|
||||
CLEAR_BIT(PWR->CR1,PWR_CR1_LPR);
|
||||
}
|
||||
|
||||
/* Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
/* Select Stop mode entry --------------------------------------------------*/
|
||||
if(STOPEntry == PWR_STOPENTRY_WFI)
|
||||
{
|
||||
/* Request Wait For Interrupt */
|
||||
__WFI();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Request Wait For Event */
|
||||
__SEV();
|
||||
__WFE();
|
||||
__WFE();
|
||||
}
|
||||
|
||||
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable Sleep-On-Exit Cortex feature
|
||||
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the
|
||||
* processor enters SLEEP or DEEPSLEEP mode when an interruption
|
||||
* handling is over returning to thread mode. Setting this bit is
|
||||
* useful when the processor is expected to run only on interruptions
|
||||
* handling.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableSleepOnExit(void)
|
||||
{
|
||||
/* Set SLEEPONEXIT bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Sleep-On-Exit Cortex feature
|
||||
* @note Clear SLEEPONEXIT bit of SCR register. When this bit is set, the
|
||||
* processor enters SLEEP or DEEPSLEEP mode when an interruption
|
||||
* handling is over.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableSleepOnExit(void)
|
||||
{
|
||||
/* Clear SLEEPONEXIT bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPONEXIT_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable Cortex Sev On Pending feature.
|
||||
* @note Set SEVONPEND bit of SCR register. When this bit is set, enabled
|
||||
* events and all interrupts, including disabled ones can wakeup
|
||||
* processor from WFE.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableSEVOnPend(void)
|
||||
{
|
||||
/* Set SEVONPEND bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable Cortex Sev On Pending feature.
|
||||
* @note Clear SEVONPEND bit of SCR register. When this bit is clear, only
|
||||
* enable interrupts or events can wakeup processor from WFE
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableSEVOnPend(void)
|
||||
{
|
||||
/* Clear SEVONPEND bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
|
||||
}
|
||||
|
||||
#if defined(PWR_PVD_SUPPORT)
|
||||
/**
|
||||
* @brief This function handles the PWR PVD interrupt request.
|
||||
* @note This API should be called under the PVD_IRQHandler().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_PVD_IRQHandler(void)
|
||||
{
|
||||
/* Check PWR exti Rising flag */
|
||||
if(__HAL_PWR_PVD_EXTI_GET_FLAG() != 0x0U)
|
||||
{
|
||||
/* Clear PVD exti pending bit */
|
||||
__HAL_PWR_PVD_EXTI_CLEAR_FLAG();
|
||||
|
||||
/* PWR PVD interrupt rising user callback */
|
||||
HAL_PWR_PVD_Callback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PWR PVD interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWR_PVD_Callback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified; when the callback is needed,
|
||||
the HAL_PWR_PVD_Callback can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
1440
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rcc.c
Normal file
1440
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rcc.c
Normal file
@@ -0,0 +1,1440 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_rcc.c
|
||||
* @author MCU Application Team
|
||||
* @brief RCC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Reset and Clock Control (RCC) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### RCC specific features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
After reset the device is running from High Speed Internal oscillator
|
||||
(from 4 MHz to reach 24MHz) with Flash 0 wait state. Flash prefetch buffer,
|
||||
D-Cache and I-Cache are disabled, and all peripherals are off except internal
|
||||
SRAM, Flash and JTAG.
|
||||
|
||||
(+) There is no prescaler on High speed (AHB) and Low speed (APB) busses:
|
||||
all peripherals mapped on these busses are running at HSI speed.
|
||||
(+) The clock for all peripherals is switched off, except the SRAM and FLASH.
|
||||
(+) All GPIOs are in analog mode, except the JTAG pins which
|
||||
are assigned to be used for debug purpose.
|
||||
|
||||
[..]
|
||||
Once the device started from reset, the user application has to:
|
||||
(+) Configure the clock source to be used to drive the System clock
|
||||
(if the application needs higher frequency/performance)
|
||||
(+) Configure the System clock frequency and Flash settings
|
||||
(+) Configure the AHB and APB busses prescalers
|
||||
(+) Enable the clock for the peripheral(s) to be used
|
||||
(+) Configure the clock source(s) for peripherals which clocks are not
|
||||
derived from the System clock (RTC, ADC, RNG, HSTIM)
|
||||
|
||||
@endverbatim
|
||||
|
||||
******************************************************************************
|
||||
* @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 RCC RCC
|
||||
* @brief RCC HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Constants RCC Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define CLOCKSWITCH_TIMEOUT_VALUE (5000U) /* 5 s */
|
||||
#define HSE_TIMEOUT_VALUE HSE_STARTUP_TIMEOUT
|
||||
#define HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
|
||||
#define LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
#define PLL_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
|
||||
|
||||
#define PLLSOURCE_NONE (0U)
|
||||
#define PLLSOURCE_FREQ_MIN (16000000U)
|
||||
#define PLLSOURCE_FREQ_MAX (24000000U)
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Macros RCC Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define RCC_PLL_OSCSOURCE_CONFIG(__HAL_RCC_PLLSOURCE__) \
|
||||
(MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, (uint32_t)(__HAL_RCC_PLLSOURCE__)))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup RCC_Private_Variables RCC Private Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
static uint32_t RCC_GetHSIFreq(void);
|
||||
#endif
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions RCC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to configure the internal and external oscillators
|
||||
(HSE, HSI, LSE, LSI, PLL, CSS and MCO) and the System busses clocks (SYSCLK, AHB, APB)
|
||||
|
||||
[..] Internal/external clock and PLL configuration
|
||||
(+) HSI (high-speed internal): 8 MHz factory-trimmed RC used directly or through
|
||||
the PLL as System clock source.
|
||||
|
||||
(+) LSI (low-speed internal): 32 KHz low consumption RC used as IWDG and/or RTC
|
||||
clock source.
|
||||
|
||||
(+) HSE (high-speed external): 4 to 48 MHz crystal oscillator used directly or
|
||||
through the PLL as System clock source. Can be used also optionally as RTC clock source.
|
||||
|
||||
(+) LSE (low-speed external): 32.768 KHz oscillator used optionally as RTC clock source.
|
||||
|
||||
(+) PLL (clocked by HSI, HSE) providing up to three independent output clocks:
|
||||
|
||||
|
||||
(+) CSS (Clock security system): once enabled, if a HSE clock failure occurs
|
||||
(HSE used directly or through PLL as System clock source), the System clock
|
||||
is automatically switched respectively to HSI or LSI and an interrupt is generated
|
||||
if enabled. The interrupt is linked to the Cortex-M0+ NMI (Non-Maskable Interrupt)
|
||||
exception vector.
|
||||
|
||||
(+) MCO (microcontroller clock output): used to output LSI, HSI, LSE, HSE or
|
||||
main PLL clock (through a configurable prescaler) on PA8 pin.
|
||||
|
||||
[..] System, AHB and APB busses clocks configuration
|
||||
(+) Several clock sources can be used to drive the System clock (SYSCLK): HSI,
|
||||
HSE, LSI, LSE and main PLL.
|
||||
The AHB clock (HCLK) is derived from System clock through configurable
|
||||
prescaler and used to clock the CPU, memory and peripherals mapped
|
||||
on AHB bus (DMA, GPIO...).and APB (PCLK1) clock is derived
|
||||
from AHB clock through configurable prescalers and used to clock
|
||||
the peripherals mapped on these busses. You can use
|
||||
"@ref HAL_RCC_GetSysClockFreq()" function to retrieve the frequencies of these clocks.
|
||||
|
||||
-@- All the peripheral clocks are derived from the System clock (SYSCLK) except:
|
||||
|
||||
(+@) RTC: the RTC clock can be derived either from the LSI, LSE or HSE clock
|
||||
divided by 2 to 31.
|
||||
You have to use @ref __HAL_RCC_RTC_ENABLE() and @ref HAL_RCCEx_PeriphCLKConfig() function
|
||||
to configure this clock.
|
||||
|
||||
(+@) RNG(*) requires a frequency equal or lower than 48 MHz.
|
||||
This clock is derived from the main PLL or HSI or System clock.
|
||||
(*) available on certain devices only
|
||||
|
||||
(+@) IWDG clock which is always the LSI clock.
|
||||
|
||||
|
||||
(+) The maximum frequency of the SYSCLK, HCLK, PCLK is 48 MHz.
|
||||
Depending on the device voltage range, the maximum frequency should be
|
||||
adapted accordingly.
|
||||
|
||||
@endverbatim
|
||||
|
||||
|
||||
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset the RCC clock configuration to the default reset state.
|
||||
* @note The default reset state of the clock configuration is given below:
|
||||
* - HSI ON and used as system clock source
|
||||
* - HSE, PLL OFF
|
||||
* - AHB and APB prescaler set to 1.
|
||||
* - CSS, MCO1 OFF
|
||||
* - All interrupts disabled
|
||||
* @note This function does not modify the configuration of the
|
||||
* - Peripheral clocks
|
||||
* - LSI, LSE and RTC clocks
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_DeInit(void)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Set HSION bit to the reset value */
|
||||
SET_BIT(RCC->CR, RCC_CR_HSION);
|
||||
|
||||
/* Wait till HSI is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set ICSCR to the reset value */
|
||||
RCC->ICSCR = 0x00FF10FF;
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Reset CFGR register (HSI is selected as system clock source) */
|
||||
RCC->CFGR = 0x00000000u;
|
||||
|
||||
/* Wait till HSI is ready */
|
||||
while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear CR register in 2 steps: first to clear HSEON in case bypass was enabled */
|
||||
RCC->CR = RCC_CR_HSION;
|
||||
|
||||
/* Then again to HSEBYP in case bypass was enabled */
|
||||
RCC->CR = RCC_CR_HSION;
|
||||
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* once PLL is OFF, reset PLLCFGR register to default value */
|
||||
RCC->PLLCFGR = 0x00000000u;
|
||||
#endif
|
||||
/* Disable all interrupts */
|
||||
RCC->CIER = 0x00000000u;
|
||||
|
||||
/* Clear all flags */
|
||||
RCC->CICR = 0xFFFFFFFFu;
|
||||
|
||||
/* Update the SystemCoreClock global variable */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
|
||||
/* Adapt Systick interrupt period */
|
||||
if (HAL_InitTick(uwTickPrio) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the RCC Oscillators according to the specified parameters in the
|
||||
* @ref RCC_OscInitTypeDef.
|
||||
* @param RCC_OscInitStruct pointer to a @ref RCC_OscInitTypeDef structure that
|
||||
* contains the configuration information for the RCC Oscillators.
|
||||
* @note The PLL is not disabled when used as system clock.
|
||||
* @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not
|
||||
* supported by this function. User should request a transition to HSE Off
|
||||
* first and then to HSE On or HSE Bypass.
|
||||
* @note Transition LSE Bypass to LSE On and LSE On to LSE Bypass are not
|
||||
* supported by this function. User should request a transition to LSE Off
|
||||
* first and then to LSE On or LSE Bypass.
|
||||
* @note Depending on devices and packages, some clocks may not be available.
|
||||
* Refer to device datasheet for clocks availability.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
uint32_t temp_sysclksrc;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
uint32_t temp_pllckcfg;
|
||||
#endif
|
||||
/* Check Null pointer */
|
||||
if (RCC_OscInitStruct == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType));
|
||||
|
||||
/*------------------------------- HSE Configuration ------------------------*/
|
||||
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState));
|
||||
|
||||
temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
|
||||
|
||||
/* When the HSE is used as system clock or clock source for PLL in these cases it is not allowed to be disabled */
|
||||
if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSE)) || (temp_sysclksrc == RCC_CFGR_SWS_HSE))
|
||||
#else
|
||||
if (temp_sysclksrc == RCC_CFGR_SWS_HSE)
|
||||
#endif
|
||||
{
|
||||
if ((READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set frequency range of the HSE */
|
||||
if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
|
||||
{
|
||||
assert_param(IS_RCC_HSE_FREQ(RCC_OscInitStruct->HSEFreq));
|
||||
|
||||
if (RCC_OscInitStruct->HSEFreq != 0)
|
||||
{
|
||||
MODIFY_REG(RCC->ECSCR, RCC_ECSCR_HSE_FREQ_Msk, RCC_OscInitStruct->HSEFreq);
|
||||
} else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the new HSE configuration ---------------------------------------*/
|
||||
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
|
||||
|
||||
/* Check the HSE State */
|
||||
if (RCC_OscInitStruct->HSEState != RCC_HSE_OFF)
|
||||
{
|
||||
#ifndef RCC_NO_DETECT_HSE_READY
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSE is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSE is disabled */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------- HSI Configuration --------------------------*/
|
||||
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState));
|
||||
assert_param(IS_RCC_HSI_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue));
|
||||
assert_param(IS_RCC_HSIDIV(RCC_OscInitStruct->HSIDiv));
|
||||
|
||||
/* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */
|
||||
temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
temp_pllckcfg = __HAL_RCC_GET_PLL_OSCSOURCE();
|
||||
if (((temp_sysclksrc == RCC_CFGR_SWS_PLL) && (temp_pllckcfg == RCC_PLLSOURCE_HSI)) || (temp_sysclksrc == RCC_CFGR_SWS_HSI))
|
||||
#else
|
||||
if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
|
||||
#endif
|
||||
{
|
||||
/* When HSI is used as system clock or as PLL input clock it can not be disabled */
|
||||
if ((READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U) && (RCC_OscInitStruct->HSIState == RCC_HSI_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Otherwise, just the calibration is allowed */
|
||||
else
|
||||
{
|
||||
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
|
||||
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_sysclksrc == RCC_CFGR_SWS_HSI)
|
||||
{
|
||||
/* Adjust the HSI division factor */
|
||||
__HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
|
||||
|
||||
/* Update the SystemCoreClock global variable with HSISYS value */
|
||||
SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
|
||||
}
|
||||
|
||||
/* Adapt Systick interrupt period */
|
||||
if (HAL_InitTick(uwTickPrio) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the HSI State */
|
||||
if (RCC_OscInitStruct->HSIState != RCC_HSI_OFF)
|
||||
{
|
||||
/* Configure the HSI division factor */
|
||||
__HAL_RCC_HSI_CONFIG(RCC_OscInitStruct->HSIDiv);
|
||||
|
||||
/* Enable the Internal High Speed oscillator (HSI). */
|
||||
__HAL_RCC_HSI_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/
|
||||
__HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal High Speed oscillator (HSI). */
|
||||
__HAL_RCC_HSI_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till HSI is disabled */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*------------------------------ LSI Configuration -------------------------*/
|
||||
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState));
|
||||
|
||||
/* Check if LSI is used as system clock */
|
||||
if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
|
||||
{
|
||||
/* When LSI is used as system clock it will not be disabled */
|
||||
if ((((RCC->CSR) & RCC_CSR_LSIRDY) != 0U) && (RCC_OscInitStruct->LSIState == RCC_LSI_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the LSI State */
|
||||
if (RCC_OscInitStruct->LSIState != RCC_LSI_OFF)
|
||||
{
|
||||
/* Enable the Internal Low Speed oscillator (LSI). */
|
||||
__HAL_RCC_LSI_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSI is ready */
|
||||
while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the Internal Low Speed oscillator (LSI). */
|
||||
__HAL_RCC_LSI_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSI is disabled */
|
||||
while (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > LSI_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/*------------------------------ LSE Configuration -------------------------*/
|
||||
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState));
|
||||
|
||||
/* When the LSE is used as system clock, it is not allowed disable it */
|
||||
if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
|
||||
{
|
||||
if ((((RCC->BDCR) & RCC_BDCR_LSERDY) != 0U) && (RCC_OscInitStruct->LSEState == RCC_LSE_OFF))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update LSE configuration in Backup Domain control register */
|
||||
/* Requires to enable write access to Backup Domain of necessary */
|
||||
if (__HAL_RCC_PWR_IS_CLK_DISABLED() != 0U)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
|
||||
if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
/* Enable write access to Backup domain */
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
|
||||
/* Wait for Backup domain Write protection disable */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Set driver factor of the LSE*/
|
||||
if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
|
||||
{
|
||||
if (((RCC_OscInitStruct->LSEDriver) & RCC_ECSCR_LSE_DRIVER) == 0U)
|
||||
{
|
||||
MODIFY_REG(RCC->ECSCR, RCC_ECSCR_LSE_DRIVER_Msk, RCC_ECSCR_LSE_DRIVER_1);
|
||||
} else
|
||||
{
|
||||
MODIFY_REG(RCC->ECSCR, RCC_ECSCR_LSE_DRIVER_Msk, RCC_OscInitStruct->LSEDriver);
|
||||
}
|
||||
}
|
||||
/* Set the new LSE configuration -----------------------------------------*/
|
||||
__HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState);
|
||||
|
||||
/* Check the LSE State */
|
||||
if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
|
||||
{
|
||||
#ifndef RCC_NO_DETECT_LSE_READY
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is disabled */
|
||||
while (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Restore clock configuration if changed */
|
||||
if (pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/*-------------------------------- PLL Configuration -----------------------*/
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState));
|
||||
|
||||
if (RCC_OscInitStruct->PLL.PLLState != RCC_PLL_NONE)
|
||||
{
|
||||
/* Check if the PLL is used as system clock or not */
|
||||
if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
if (RCC_OscInitStruct->PLL.PLLState == RCC_PLL_ON)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource));
|
||||
|
||||
/* Disable the main PLL. */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is cancel the ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* PLL input source frequency must be greater than or equal to PLLSOURCE_MIN_FREQ */
|
||||
if(((RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSE) && \
|
||||
(((HSE_VALUE < PLLSOURCE_FREQ_MIN)) || (HSE_VALUE > PLLSOURCE_FREQ_MAX))) || \
|
||||
((RCC_OscInitStruct->PLL.PLLSource == RCC_PLLSOURCE_HSI) && (RCC_GetHSIFreq() < PLLSOURCE_FREQ_MIN)))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Configure the main PLL clock source, multiplication and division factors. */
|
||||
__HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_OscInitStruct->PLL.PLLSource);
|
||||
|
||||
/* Enable the main PLL. */
|
||||
__HAL_RCC_PLL_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is ready */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the main PLL. */
|
||||
__HAL_RCC_PLL_DISABLE();
|
||||
|
||||
/* Disable all PLL outputs to save power */
|
||||
MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, PLLSOURCE_NONE);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL is disabled */
|
||||
while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != 0U)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if there is a request to disable the PLL used as System clock source */
|
||||
if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Do not return HAL_ERROR if request repeats the current configuration */
|
||||
temp_pllckcfg = RCC->PLLCFGR;
|
||||
|
||||
if(READ_BIT(temp_pllckcfg, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the CPU, AHB and APB busses clocks according to the specified
|
||||
* parameters in the RCC_ClkInitStruct.
|
||||
* @param RCC_ClkInitStruct pointer to a @ref RCC_ClkInitTypeDef structure that
|
||||
* contains the configuration information for the RCC peripheral.
|
||||
* @param FLatency FLASH Latency
|
||||
* This parameter can be one of the following values:
|
||||
* @arg FLASH_LATENCY_0 FLASH 0 Latency cycle
|
||||
* @arg FLASH_LATENCY_1 FLASH 1 Latency cycle
|
||||
*
|
||||
* @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency
|
||||
* and updated by @ref HAL_RCC_GetHCLKFreq() function called within this function
|
||||
*
|
||||
* @note The HSI is used by default as system clock source after
|
||||
* startup from Reset, wake-up from STANDBY mode. After restart from Reset,
|
||||
* the HSI frequency is set to 4 MHz, then it reaches its default value 8 MHz.
|
||||
*
|
||||
* @note The HSI can be selected as system clock source after
|
||||
* from STOP modes or in case of failure of the HSE used directly or indirectly
|
||||
* as system clock (if the Clock Security System CSS is enabled).
|
||||
*
|
||||
* @note The LSI can be selected as system clock source after
|
||||
* in case of failure of the LSE used directly or indirectly
|
||||
* as system clock (if the Clock Security System LSECSS is enabled).
|
||||
*
|
||||
* @note A switch from one clock source to another occurs only if the target
|
||||
* clock source is ready (clock stable after startup delay or PLL locked).
|
||||
* If a clock source which is not yet ready is selected, the switch will
|
||||
* occur when the clock source is ready.
|
||||
*
|
||||
* @note You can use @ref HAL_RCC_GetClockConfig() function to know which clock is
|
||||
* currently used as system clock source.
|
||||
*
|
||||
* @note Depending on the device voltage range, the software has to set correctly
|
||||
* HPRE[3:0] bits to ensure that HCLK not exceed the maximum allowed frequency
|
||||
* (for more details refer to section above "Initialization/de-initialization functions")
|
||||
* @retval None
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
|
||||
{
|
||||
uint32_t tickstart;
|
||||
|
||||
/* Check Null pointer */
|
||||
if (RCC_ClkInitStruct == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_CLOCKTYPE(RCC_ClkInitStruct->ClockType));
|
||||
assert_param(IS_FLASH_LATENCY(FLatency));
|
||||
|
||||
/* To correctly read data from FLASH memory, the number of wait states (LATENCY)
|
||||
must be correctly programmed according to the frequency of the FLASH clock
|
||||
(HCLK) and the supply voltage of the device. */
|
||||
|
||||
/* Increasing the number of wait states because of higher CPU frequency */
|
||||
if (FLatency > __HAL_FLASH_GET_LATENCY())
|
||||
{
|
||||
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
||||
__HAL_FLASH_SET_LATENCY(FLatency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by polling the FLASH_ACR register */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- HCLK Configuration --------------------------*/
|
||||
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_HCLK) == RCC_CLOCKTYPE_HCLK)
|
||||
{
|
||||
/* Set the highest APB divider in order to ensure that we do not go through
|
||||
a non-spec phase whatever we decrease or increase HCLK. */
|
||||
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
|
||||
{
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_HCLK_DIV16);
|
||||
}
|
||||
|
||||
/* Set the new HCLK clock divider */
|
||||
assert_param(IS_RCC_HCLK(RCC_ClkInitStruct->AHBCLKDivider));
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_ClkInitStruct->AHBCLKDivider);
|
||||
}
|
||||
|
||||
/*------------------------- SYSCLK Configuration ---------------------------*/
|
||||
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_SYSCLK) == RCC_CLOCKTYPE_SYSCLK)
|
||||
{
|
||||
assert_param(IS_RCC_SYSCLKSOURCE(RCC_ClkInitStruct->SYSCLKSource));
|
||||
|
||||
/* HSE is selected as System Clock Source */
|
||||
if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSE)
|
||||
{
|
||||
/* Check the HSE ready flag */
|
||||
if (READ_BIT(RCC->CR, RCC_CR_HSERDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* HSI is selected as System Clock Source */
|
||||
else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSI)
|
||||
{
|
||||
/* Check the HSI ready flag */
|
||||
if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* PLL is selected as System Clock Source */
|
||||
else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_PLLCLK)
|
||||
{
|
||||
/* Check the PLL ready flag */
|
||||
if (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/* LSE is selected as System Clock Source */
|
||||
else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_LSE)
|
||||
{
|
||||
/* Check the LSE ready flag */
|
||||
if (READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* LSI is selected as System Clock Source */
|
||||
else
|
||||
{
|
||||
/* Check the LSI ready flag */
|
||||
if (READ_BIT(RCC->CSR, RCC_CSR_LSIRDY) == 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_ClkInitStruct->SYSCLKSource);
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while (__HAL_RCC_GET_SYSCLK_SOURCE() != (RCC_ClkInitStruct->SYSCLKSource << RCC_CFGR_SWS_Pos))
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Decreasing the number of wait states because of lower CPU frequency */
|
||||
if (FLatency < __HAL_FLASH_GET_LATENCY())
|
||||
{
|
||||
/* Program the new number of wait states to the LATENCY bits in the FLASH_ACR register */
|
||||
__HAL_FLASH_SET_LATENCY(FLatency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by polling the FLASH_ACR register */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while ((FLASH->ACR & FLASH_ACR_LATENCY) != FLatency)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------- PCLK1 Configuration ---------------------------*/
|
||||
if (((RCC_ClkInitStruct->ClockType) & RCC_CLOCKTYPE_PCLK1) == RCC_CLOCKTYPE_PCLK1)
|
||||
{
|
||||
assert_param(IS_RCC_PCLK(RCC_ClkInitStruct->APB1CLKDivider));
|
||||
MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE, RCC_ClkInitStruct->APB1CLKDivider);
|
||||
}
|
||||
|
||||
/* Update the SystemCoreClock global variable */
|
||||
SystemCoreClock = (HAL_RCC_GetSysClockFreq() >> ((AHBPrescTable[(RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos]) & 0x1FU));
|
||||
|
||||
/* Configure the source of time base considering new system clocks settings*/
|
||||
return HAL_InitTick(uwTickPrio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RCC_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief RCC clocks control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to:
|
||||
|
||||
(+) Ouput clock to MCO pin.
|
||||
(+) Retrieve current clock frequencies.
|
||||
(+) Enable the Clock Security System.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Select the clock source to output on MCO pin(PA8).
|
||||
* @note PA8 should be configured in alternate function mode.
|
||||
* @param RCC_MCOx specifies the output direction for the clock source.
|
||||
* @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA8).
|
||||
* @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PA1).
|
||||
* @arg @ref RCC_MCO3 Clock source to output on MCO3 pin(PA5).
|
||||
* @arg @ref RCC_MCO4 Clock source to output on MCO4 pin(PA9).
|
||||
* @arg @ref RCC_MCO5 Clock source to output on MCO5 pin(PA13).
|
||||
* @arg @ref RCC_MCO6 Clock source to output on MCO6 pin(PA14).
|
||||
* @arg @ref RCC_MCO7 Clock source to output on MCO7 pin(PF2).
|
||||
* @param RCC_MCOSource specifies the clock source to output.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_MCO1SOURCE_NOCLOCK MCO output disabled, no clock on MCO
|
||||
* @arg @ref RCC_MCO1SOURCE_SYSCLK system clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_HSI HSI clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_HSE HSE clock selected as MCO sourcee
|
||||
* @arg @ref RCC_MCO1SOURCE_PLLCLK main PLL clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_LSI LSI clock selected as MCO source
|
||||
* @arg @ref RCC_MCO1SOURCE_LSE LSE clock selected as MCO source
|
||||
* @note Depending on devices and packages, some clocks may not be available.
|
||||
* Refer to device datasheet for clocks availability.
|
||||
* @param RCC_MCODiv specifies the MCO prescaler.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_MCODIV_1 no division applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_2 division by 2 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_4 division by 4 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_8 division by 8 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_16 division by 16 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_32 division by 32 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_64 division by 64 applied to MCO clock
|
||||
* @arg @ref RCC_MCODIV_128 division by 128 applied to MCO clock
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_MCOConfig(uint32_t RCC_MCOx, uint32_t RCC_MCOSource, uint32_t RCC_MCODiv)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_MCO(RCC_MCOx));
|
||||
assert_param(IS_RCC_MCODIV(RCC_MCODiv));
|
||||
assert_param(IS_RCC_MCO1SOURCE(RCC_MCOSource));
|
||||
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
switch(RCC_MCOx)
|
||||
{
|
||||
case RCC_MCO2 : /* Configure PA01 as the clock output */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_1;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO3 : /* Configure PA05 as the clock output */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_5;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO4 : /* Configure PA09 as the clock output */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO5 : /* Configure PA13 as the clock output. Note:PA13 is SWD_SWDIO Pin */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_13;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO6 : /* Configure PA14 as the clock output. Note:PA14 is SWD_SWCLK Pin */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_14;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF15_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO7 : /* Configure PF02 as the clock output. Note:Defaults to the reset pin, Optionbyte needs to be configured */
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF6_MCO;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
|
||||
break;
|
||||
case RCC_MCO1 : /* PA08 */
|
||||
default :
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_8;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_MCO;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Mask MCOSEL[] and MCOPRE[] bits then set MCO1 clock source and prescaler */
|
||||
MODIFY_REG(RCC->CFGR, (RCC_CFGR_MCOSEL | RCC_CFGR_MCOPRE), (RCC_MCOSource | RCC_MCODiv));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the SYSCLK frequency.
|
||||
*
|
||||
* @note The system frequency computed by this function is not the real
|
||||
* frequency in the chip. It is calculated based on the predefined
|
||||
* constant and the selected clock source:
|
||||
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE/HSIDIV(*)
|
||||
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**)
|
||||
* @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(**),
|
||||
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
|
||||
* @note If SYSCLK source is LSI, function returns values based on LSI_VALUE(***)
|
||||
* @note If SYSCLK source is LSE, function returns values based on LSE_VALUE(****)
|
||||
* @note (*) HSI_VALUE is a constant defined in py32f0xx_hal_conf.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
* @note (**) HSE_VALUE is a constant defined in py32f0xx_hal_conf.h file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
* @note (***) LSE_VALUE is a constant defined in py32f0xx_hal_conf.h file (default value
|
||||
* 32768 Hz).
|
||||
* @note (****) LSI_VALUE is a constant defined in py32f0xx_hal_conf.h file (default value
|
||||
* 32768 Hz).
|
||||
*
|
||||
* @note Depending on devices and packages, some clocks may not be available.
|
||||
* Refer to device datasheet for clocks availability.
|
||||
*
|
||||
* @note The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
*
|
||||
* @note This function can be used by the user application to compute the
|
||||
* baudrate for the communication peripherals or configure other parameters.
|
||||
*
|
||||
* @note Each time SYSCLK changes, this function must be called to update the
|
||||
* right SYSCLK value. Otherwise, any configuration based on this function will be incorrect.
|
||||
*
|
||||
*
|
||||
* @retval SYSCLK frequency
|
||||
*/
|
||||
uint32_t HAL_RCC_GetSysClockFreq(void)
|
||||
{
|
||||
uint32_t hsidiv;
|
||||
uint32_t sysclockfreq;
|
||||
const uint32_t hsiValue[5] = {4000000,8000000,16000000,22120000,24000000};
|
||||
uint32_t hsiIndex;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
uint32_t pllsource;
|
||||
#endif
|
||||
|
||||
if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI)
|
||||
{
|
||||
/* HSISYS can be derived for HSI */
|
||||
hsidiv = (1UL << ((READ_BIT(RCC->CR, RCC_CR_HSIDIV)) >> RCC_CR_HSIDIV_Pos));
|
||||
|
||||
/* HSISYS used as system clock source */
|
||||
hsiIndex = (RCC->ICSCR&RCC_ICSCR_HSI_FS_Msk)>>RCC_ICSCR_HSI_FS_Pos;
|
||||
if (hsiIndex > 4)
|
||||
{
|
||||
hsiIndex = 0;
|
||||
}
|
||||
sysclockfreq = (hsiValue[hsiIndex] / hsidiv);
|
||||
}
|
||||
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
|
||||
{
|
||||
/* HSE used as system clock source */
|
||||
sysclockfreq = HSE_VALUE;
|
||||
}
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL)
|
||||
{
|
||||
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
sysclockfreq = HSE_VALUE * 2;
|
||||
break;
|
||||
|
||||
case RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
hsiIndex = (RCC->ICSCR&RCC_ICSCR_HSI_FS_Msk)>>RCC_ICSCR_HSI_FS_Pos;
|
||||
if (hsiIndex > 4)
|
||||
{
|
||||
hsiIndex = 0;
|
||||
}
|
||||
sysclockfreq = hsiValue[hsiIndex] * 2;
|
||||
break;
|
||||
|
||||
default: /* HSI used as PLL clock source */
|
||||
sysclockfreq = hsiValue[4] * 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
|
||||
{
|
||||
/* LSE used as system clock source */
|
||||
sysclockfreq = LSE_VALUE;
|
||||
}
|
||||
#endif
|
||||
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
|
||||
{
|
||||
/* LSI used as system clock source */
|
||||
sysclockfreq = LSI_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
sysclockfreq = 0U;
|
||||
}
|
||||
|
||||
return sysclockfreq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the HCLK frequency.
|
||||
* @note Each time HCLK changes, this function must be called to update the
|
||||
* right HCLK value. Otherwise, any configuration based on this function will be incorrect.
|
||||
*
|
||||
* @note The SystemCoreClock CMSIS variable is used to store System Clock Frequency.
|
||||
* @retval HCLK frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCC_GetHCLKFreq(void)
|
||||
{
|
||||
return SystemCoreClock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the PCLK1 frequency.
|
||||
* @note Each time PCLK1 changes, this function must be called to update the
|
||||
* right PCLK1 value. Otherwise, any configuration based on this function will be incorrect.
|
||||
* @retval PCLK1 frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCC_GetPCLK1Freq(void)
|
||||
{
|
||||
/* Get HCLK source and Compute PCLK1 frequency ---------------------------*/
|
||||
return (uint32_t)((HAL_RCC_GetHCLKFreq()) >> (APBPrescTable[(RCC->CFGR & RCC_CFGR_PPRE) >> RCC_CFGR_PPRE_Pos] & 0x1FU));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the RCC_OscInitStruct according to the internal
|
||||
* RCC configuration registers.
|
||||
* @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that
|
||||
* will be configured.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(RCC_OscInitStruct != (void *)NULL);
|
||||
|
||||
/* Set all possible values for the Oscillator type parameter ---------------*/
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
|
||||
RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
|
||||
#else
|
||||
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
|
||||
RCC_OSCILLATORTYPE_LSI;
|
||||
#endif
|
||||
/* Get the HSE configuration -----------------------------------------------*/
|
||||
if ((RCC->CR & RCC_CR_HSEBYP) == RCC_CR_HSEBYP)
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS;
|
||||
}
|
||||
else if ((RCC->CR & RCC_CR_HSEON) == RCC_CR_HSEON)
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->HSEState = RCC_HSE_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->HSEFreq = (RCC->ECSCR & RCC_ECSCR_HSE_FREQ);
|
||||
|
||||
/* Get the HSI configuration -----------------------------------------------*/
|
||||
if ((RCC->CR & RCC_CR_HSION) == RCC_CR_HSION)
|
||||
{
|
||||
RCC_OscInitStruct->HSIState = RCC_HSI_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->HSIState = RCC_HSI_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->HSICalibrationValue = (RCC->ICSCR & (RCC_ICSCR_HSI_FS | RCC_ICSCR_HSI_TRIM));
|
||||
RCC_OscInitStruct->HSIDiv = (RCC->CR & RCC_CR_HSIDIV);
|
||||
|
||||
/* Get the LSI configuration -----------------------------------------------*/
|
||||
if ((RCC->CSR & RCC_CSR_LSION) == RCC_CSR_LSION)
|
||||
{
|
||||
RCC_OscInitStruct->LSIState = RCC_LSI_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->LSIState = RCC_LSI_OFF;
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/* Get the LSE configuration -----------------------------------------------*/
|
||||
if ((RCC->BDCR & RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP)
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS;
|
||||
}
|
||||
else if ((RCC->BDCR & RCC_BDCR_LSEON) == RCC_BDCR_LSEON)
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->LSEState = RCC_LSE_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->LSEDriver = (RCC->ECSCR & RCC_ECSCR_LSE_DRIVER);
|
||||
#endif
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* Get the PLL configuration -----------------------------------------------*/
|
||||
if ((RCC->CR & RCC_CR_PLLON) == RCC_CR_PLLON)
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON;
|
||||
}
|
||||
else
|
||||
{
|
||||
RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF;
|
||||
}
|
||||
|
||||
RCC_OscInitStruct->PLL.PLLSource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the RCC_ClkInitStruct according to the internal
|
||||
* RCC configuration registers.
|
||||
* @param RCC_ClkInitStruct Pointer to a @ref RCC_ClkInitTypeDef structure that
|
||||
* will be configured.
|
||||
* @param pFLatency Pointer on the Flash Latency.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_GetClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t *pFLatency)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(RCC_ClkInitStruct != (void *)NULL);
|
||||
assert_param(pFLatency != (void *)NULL);
|
||||
|
||||
/* Set all possible values for the Clock type parameter --------------------*/
|
||||
RCC_ClkInitStruct->ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1;
|
||||
|
||||
/* Get the SYSCLK configuration --------------------------------------------*/
|
||||
RCC_ClkInitStruct->SYSCLKSource = (uint32_t)(RCC->CFGR & RCC_CFGR_SW);
|
||||
|
||||
/* Get the HCLK configuration ----------------------------------------------*/
|
||||
RCC_ClkInitStruct->AHBCLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_HPRE);
|
||||
|
||||
/* Get the APB1 configuration ----------------------------------------------*/
|
||||
RCC_ClkInitStruct->APB1CLKDivider = (uint32_t)(RCC->CFGR & RCC_CFGR_PPRE);
|
||||
|
||||
|
||||
/* Get the Flash Wait State (Latency) configuration ------------------------*/
|
||||
*pFLatency = (uint32_t)(FLASH->ACR & FLASH_ACR_LATENCY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Clock Security System.
|
||||
* @note If a failure is detected on the HSE oscillator clock, this oscillator
|
||||
* is automatically disabled and an interrupt is generated to inform the
|
||||
* software about the failure (Clock Security System Interrupt, CSSI),
|
||||
* allowing the MCU to perform rescue operations. The CSSI is linked to
|
||||
* the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
|
||||
* @note The Clock Security System can only be cleared by reset.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_EnableCSS(void)
|
||||
{
|
||||
SET_BIT(RCC->CR, RCC_CR_CSSON) ;
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/**
|
||||
* @brief Enable the LSE Clock Security System.
|
||||
* @note If a failure is detected on the LSE oscillator clock, this oscillator
|
||||
* is automatically disabled and an interrupt is generated to inform the
|
||||
* software about the failure (Clock Security System Interrupt, CSSI),
|
||||
* allowing the MCU to perform rescue operations. The CSSI is linked to
|
||||
* the Cortex-M0+ NMI (Non-Maskable Interrupt) exception vector.
|
||||
* @note The LSE Clock Security System Detection bit (LSECSSD in BDCR) can only be
|
||||
* cleared by a backup domain reset.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_EnableLSECSS(void)
|
||||
{
|
||||
SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the LSE Clock Security System.
|
||||
* @note After LSE failure detection, the software must disable LSECSSON
|
||||
* @note The Clock Security System can only be cleared by reset otherwise.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_DisableLSECSS(void)
|
||||
{
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Handle the RCC Clock Security System interrupt request.
|
||||
* @note This API should be called under the NMI_Handler().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCC_NMI_IRQHandler(void)
|
||||
{
|
||||
uint32_t itflag = RCC->CIFR;
|
||||
|
||||
/* Clear interrupt flags related to CSS */
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
RCC->CICR = (itflag & (RCC_CIFR_CSSF | RCC_CIFR_LSECSSF));
|
||||
#else
|
||||
RCC->CICR = (itflag & RCC_CIFR_CSSF);
|
||||
#endif
|
||||
/* Check RCC CSSF interrupt flag */
|
||||
if ((itflag & RCC_CIFR_CSSF) != 0x00u)
|
||||
{
|
||||
/* RCC Clock Security System interrupt user callback */
|
||||
HAL_RCC_CSSCallback();
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/* Check RCC LSECSSF interrupt flag */
|
||||
if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
|
||||
{
|
||||
/* RCC Clock Security System interrupt user callback */
|
||||
HAL_RCC_LSECSSCallback();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/**
|
||||
* @brief Get HSI frequency.
|
||||
* @retval HSI frequency
|
||||
*/
|
||||
static uint32_t RCC_GetHSIFreq(void)
|
||||
{
|
||||
uint32_t hsifs;
|
||||
|
||||
hsifs = ((READ_BIT(RCC->ICSCR, RCC_ICSCR_HSI_FS)) >> RCC_ICSCR_HSI_FS_Pos);
|
||||
|
||||
return HSIFreqTable[hsifs%8];
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @brief Handle the RCC HSE Clock Security System interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCC_CSSCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the @ref HAL_RCC_CSSCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/**
|
||||
* @brief RCC LSE Clock Security System interrupt callback.
|
||||
* @retval none
|
||||
*/
|
||||
__weak void HAL_RCC_LSECSSCallback(void)
|
||||
{
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_RCC_LSECSSCallback should be implemented in the user file
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
612
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rcc_ex.c
Normal file
612
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rcc_ex.c
Normal file
@@ -0,0 +1,612 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_rcc_ex.c
|
||||
* @author MCU Application Team
|
||||
* @brief Extended RCC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities RCC extended peripheral:
|
||||
* + Extended Peripheral Control functions
|
||||
* + Extended Clock management functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @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 RCCEx RCCEx
|
||||
* @brief RCC Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define PLL_TIMEOUT_VALUE 100U /* 100 ms (minimum Tick + 1) */
|
||||
|
||||
#if defined(RCC_BDCR_LSCOEN)
|
||||
#define LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
||||
#define LSCO_GPIO_PORT GPIOA
|
||||
#define LSCO_PIN (GPIO_PIN_9 |GPIO_PIN_10)
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
|
||||
* @brief Extended Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the RCC Clocks
|
||||
frequencies.
|
||||
[..]
|
||||
(@) Important note: Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to
|
||||
select the RTC clock source; in this case the Backup domain will be reset in
|
||||
order to modify the RTC Clock source, as consequence RTC registers (including
|
||||
the backup registers) and RCC_BDCR register are set to their reset values.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initialize the RCC extended peripherals clocks according to the specified
|
||||
* parameters in the @ref RCC_PeriphCLKInitTypeDef.
|
||||
* @param PeriphClkInit pointer to a @ref RCC_PeriphCLKInitTypeDef structure that
|
||||
* contains a field PeriphClockSelection which can be a combination of the following values:
|
||||
* @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock (1)
|
||||
* @arg @ref RCC_PERIPHCLK_PVD PVD peripheral clock (1)
|
||||
* @arg @ref RCC_PERIPHCLK_COMP1 COMP1 peripheral clock (1)
|
||||
* @arg @ref RCC_PERIPHCLK_COMP2 COMP2 peripheral clock (1)
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM LPTIM peripheral clock (1)
|
||||
*
|
||||
* @note (1) Peripherals maybe not available on some devices
|
||||
* @note Care must be taken when @ref HAL_RCCEx_PeriphCLKConfig() is used to select
|
||||
* the RTC clock source: in this case the access to Backup domain is enabled.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
uint32_t tickstart = 0U, temp_reg = 0U;
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
#endif
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
/*------------------------------- RTC Configuration ------------------------*/
|
||||
if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
|
||||
{
|
||||
/* check for RTC Parameters used to output RTCCLK */
|
||||
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
|
||||
|
||||
/* As soon as function is called to change RTC clock source, activation of the
|
||||
power domain is done. */
|
||||
/* Requires to enable write access to Backup Domain of necessary */
|
||||
if (__HAL_RCC_PWR_IS_CLK_DISABLED())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
|
||||
if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
/* Enable write access to Backup domain */
|
||||
SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
||||
|
||||
/* Wait for Backup domain Write protection disable */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
|
||||
temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
|
||||
if ((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
|
||||
{
|
||||
/* Store the content of BDCR register before the reset of Backup Domain */
|
||||
temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
|
||||
/* RTC Clock selection can be changed only if the Backup Domain is reset */
|
||||
__HAL_RCC_BACKUPRESET_FORCE();
|
||||
__HAL_RCC_BACKUPRESET_RELEASE();
|
||||
/* Restore the Content of BDCR register */
|
||||
RCC->BDCR = temp_reg;
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/* Wait for LSERDY if LSE was enabled */
|
||||
if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
|
||||
{
|
||||
/* Get Start Tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while (__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
__HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
||||
|
||||
/* Require to disable power clock if necessary */
|
||||
if (pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
#endif /*RCC_BDCR_RTCSEL*/
|
||||
|
||||
#if defined(RCC_CCIPR_PVDSEL)
|
||||
/*-------------------------- PVD clock source configuration -------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PVD) == RCC_PERIPHCLK_PVD)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PVDCLKSOURCE(PeriphClkInit->PvdClockSelection));
|
||||
|
||||
/* Configure the PVD clock source */
|
||||
__HAL_RCC_PVD_CONFIG(PeriphClkInit->PvdClockSelection);
|
||||
}
|
||||
#endif /* RCC_CCIPR_PVDSEL */
|
||||
|
||||
#if defined(RCC_CCIPR_COMP1SEL)
|
||||
/*-------------------------- COMP1 clock source configuration -------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_COMP1) == RCC_PERIPHCLK_COMP1)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_COMP1CLKSOURCE(PeriphClkInit->Comp1ClockSelection));
|
||||
|
||||
/* Configure the COMP1 clock source */
|
||||
__HAL_RCC_COMP1_CONFIG(PeriphClkInit->Comp1ClockSelection);
|
||||
}
|
||||
#endif /* RCC_CCIPR_COMP1SEL */
|
||||
|
||||
#if defined(RCC_CCIPR_COMP2SEL)
|
||||
/*-------------------------- COMP2 clock source configuration -------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_COMP2) == RCC_PERIPHCLK_COMP2)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_COMP2CLKSOURCE(PeriphClkInit->Comp2ClockSelection));
|
||||
|
||||
/* Configure the COMP2 clock source */
|
||||
__HAL_RCC_COMP2_CONFIG(PeriphClkInit->Comp2ClockSelection);
|
||||
}
|
||||
#endif /* RCC_CCIPR_COMP2SEL */
|
||||
|
||||
#if defined(RCC_CCIPR_LPTIMSEL)
|
||||
/*-------------------------- LPTIM clock source configuration -------------------*/
|
||||
if (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM) == (RCC_PERIPHCLK_LPTIM))
|
||||
{
|
||||
assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->LptimClockSelection));
|
||||
__HAL_RCC_LPTIM_CONFIG(PeriphClkInit->LptimClockSelection);
|
||||
}
|
||||
#endif /* RCC_CCIPR_LPTIM1SEL */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
|
||||
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
|
||||
* returns the configuration information for the Extended Peripherals
|
||||
* clocks: PVD, COMP1, COMP2, RTC, LPTIM
|
||||
* @note Depending on devices and packages, some Peripherals may not be available.
|
||||
* Refer to device datasheet for Peripheral availability.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
/* Set all possible values for the extended clock type parameter------------*/
|
||||
#if defined(PY32F002APRE)
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_LPTIM;
|
||||
#else
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_COMP1 | RCC_PERIPHCLK_COMP2 | RCC_PERIPHCLK_PVD | \
|
||||
RCC_PERIPHCLK_LPTIM | RCC_PERIPHCLK_RTC ;
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_PVDSEL)
|
||||
/* Get the PVD clock source ---------------------------------------------*/
|
||||
PeriphClkInit->PvdClockSelection = __HAL_RCC_GET_PVD_SOURCE();
|
||||
#endif /* RCC_CCIPR_PVDSEL */
|
||||
#if defined(RCC_CCIPR_COMP1SEL)
|
||||
/* Get the COMP1 clock source --------------------------------------------*/
|
||||
PeriphClkInit->Comp1ClockSelection = __HAL_RCC_GET_COMP1_SOURCE();
|
||||
#endif /* RCC_CCIPR_COMP1SEL */
|
||||
#if defined(RCC_CCIPR_COMP2SEL)
|
||||
/* Get the COMP2 clock source ---------------------------------------------*/
|
||||
PeriphClkInit->Comp2ClockSelection = __HAL_RCC_GET_COMP2_SOURCE();
|
||||
#endif /* RCC_CCIPR_COMP2SEL */
|
||||
#if defined(RCC_CCIPR_LPTIMSEL)
|
||||
/* Get the LPTIM clock source ---------------------------------------------*/
|
||||
PeriphClkInit->LptimClockSelection = __HAL_RCC_GET_LPTIM_SOURCE();
|
||||
#endif /* RCC_CCIPR_LPTIM2SEL */
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
/* Get the RTC clock source ------------------------------------------------*/
|
||||
PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
|
||||
#endif /* RCC_BDCR_RTCSEL */
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the peripheral clock frequency for peripherals with clock source from PLL
|
||||
* @note Return 0 if peripheral clock identifier not managed by this API
|
||||
* @param PeriphClk Peripheral clock identifier
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_PVD PVD peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_COMP1 COMP1 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_COMP2 COMP2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_LPTIM LPTIM peripheral clock
|
||||
* @note Depending on devices and packages, some Peripherals may not be available.
|
||||
* Refer to device datasheet for Peripheral availability.
|
||||
* @retval Frequency in Hz
|
||||
*/
|
||||
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
|
||||
{
|
||||
uint32_t frequency = 0U;
|
||||
uint32_t srcclk;
|
||||
|
||||
#if defined(RCC_CCIPR_RNGSEL)
|
||||
uint32_t rngclk;
|
||||
uint32_t rngdiv;
|
||||
#endif
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
|
||||
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
if (PeriphClk == RCC_PERIPHCLK_RTC)
|
||||
{
|
||||
/* Get the current RTC source */
|
||||
srcclk = __HAL_RCC_GET_RTC_SOURCE();
|
||||
|
||||
/* Check if LSI is ready and if RTC clock selection is LSI */
|
||||
if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (srcclk == RCC_RTCCLKSOURCE_LSI))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
/* Check if LSE is ready and if RTC clock selection is LSE */
|
||||
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_RTCCLKSOURCE_LSE))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
#endif
|
||||
/* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/
|
||||
else if ((HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)) &&(srcclk == RCC_RTCCLKSOURCE_HSE_DIV128))
|
||||
{
|
||||
frequency = HSE_VALUE / 128U;
|
||||
}
|
||||
/* Clock not enabled for RTC*/
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
/* Other external peripheral clock source than RTC */
|
||||
|
||||
switch (PeriphClk)
|
||||
{
|
||||
#if defined(RCC_CCIPR_PVDSEL)
|
||||
case RCC_PERIPHCLK_PVD:
|
||||
/* Get the current PVD source */
|
||||
srcclk = __HAL_RCC_GET_PVD_SOURCE();
|
||||
|
||||
if (srcclk == RCC_PVDCLKSOURCE_PCLK) /* PCLK1 */
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (HAL_IS_BIT_CLR(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_PVDCLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_PVDCLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for PVD */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_COMP1SEL)
|
||||
case RCC_PERIPHCLK_COMP1:
|
||||
/* Get the current COMP1 source */
|
||||
srcclk = __HAL_RCC_GET_COMP1_SOURCE();
|
||||
|
||||
if (srcclk == RCC_COMP1CLKSOURCE_PCLK) /* PCLK1 */
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (HAL_IS_BIT_CLR(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_COMP1CLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_COMP1CLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for COMP1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_COMP2SEL)
|
||||
case RCC_PERIPHCLK_COMP2:
|
||||
/* Get the current COMP2 source */
|
||||
srcclk = __HAL_RCC_GET_COMP2_SOURCE();
|
||||
|
||||
if (srcclk == RCC_COMP2CLKSOURCE_PCLK) /* PCLK1 */
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (HAL_IS_BIT_CLR(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_COMP2CLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOSEL)) \
|
||||
&& (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSCOEN)) && (srcclk == RCC_COMP2CLKSOURCE_LSC))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Clock not enabled for COMP2 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_LPTIMSEL)
|
||||
case RCC_PERIPHCLK_LPTIM:
|
||||
/* Get the current LPTIM1 source */
|
||||
srcclk = __HAL_RCC_GET_LPTIM_SOURCE();
|
||||
|
||||
if (srcclk == RCC_LPTIMCLKSOURCE_PCLK)
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK1Freq();
|
||||
}
|
||||
else if ((HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)) && (srcclk == RCC_LPTIMCLKSOURCE_LSI))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPTIMCLKSOURCE_LSE))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
#endif
|
||||
/* Clock not enabled for LPTIM1 */
|
||||
else
|
||||
{
|
||||
/* Nothing to do as frequency already initialized to 0U */
|
||||
}
|
||||
break;
|
||||
#endif /* RCC_CCIPR_LPTIM1SEL */
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
}
|
||||
#endif
|
||||
return (frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
|
||||
* @brief Extended Clock management functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended clock management functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the
|
||||
activation or deactivation of LSE CSS, Low speed clock output and
|
||||
clock after wake-up from STOP mode.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RCC_BDCR_LSCOEN)
|
||||
/**
|
||||
* @brief Select the Low Speed clock source to output on LSCO pin (PA2).
|
||||
* @param LSCOSource specifies the Low Speed clock source to output.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
|
||||
* @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
FlagStatus backupchanged = RESET;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
|
||||
|
||||
if (LSCOSource == RCC_LSCOSOURCE_LSE)
|
||||
{
|
||||
/* LSCO Pin Clock Enable */
|
||||
LSCO_CLK_ENABLE();
|
||||
|
||||
/* Configue the LSCO pin in analog mode */
|
||||
GPIO_InitStruct.Pin = LSCO_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
|
||||
}
|
||||
#endif
|
||||
/* Update LSCOSEL clock source in Backup Domain control register */
|
||||
if (__HAL_RCC_PWR_IS_CLK_DISABLED())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
backupchanged = SET;
|
||||
}
|
||||
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
|
||||
#else
|
||||
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOEN, RCC_BDCR_LSCOEN);
|
||||
#endif
|
||||
if (backupchanged == SET)
|
||||
{
|
||||
HAL_PWR_DisableBkUpAccess();
|
||||
}
|
||||
if (pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Low Speed clock output.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_DisableLSCO(void)
|
||||
{
|
||||
FlagStatus pwrclkchanged = RESET;
|
||||
FlagStatus backupchanged = RESET;
|
||||
|
||||
/* Update LSCOEN bit in Backup Domain control register */
|
||||
if (__HAL_RCC_PWR_IS_CLK_DISABLED())
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
pwrclkchanged = SET;
|
||||
}
|
||||
if (HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
||||
{
|
||||
/* Enable access to the backup domain */
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
backupchanged = SET;
|
||||
}
|
||||
|
||||
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
|
||||
|
||||
/* Restore previous configuration */
|
||||
if (backupchanged == SET)
|
||||
{
|
||||
/* Disable access to the backup domain */
|
||||
HAL_PWR_DisableBkUpAccess();
|
||||
}
|
||||
if (pwrclkchanged == SET)
|
||||
{
|
||||
__HAL_RCC_PWR_CLK_DISABLE();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
1915
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rtc.c
Normal file
1915
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rtc.c
Normal file
@@ -0,0 +1,1915 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_rtc.c
|
||||
* @author MCU Application Team
|
||||
* @brief RTC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Real Time Clock (RTC) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + RTC Time and Date functions
|
||||
* + RTC Alarm functions
|
||||
* + Peripheral Control functions
|
||||
* + Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==================================================================
|
||||
[..]
|
||||
(+) Enable the RTC domain access (see description in the section above).
|
||||
(+) Configure the RTC Prescaler (Asynchronous prescaler to generate RTC 1Hz time base)
|
||||
using the HAL_RTC_Init() function.
|
||||
|
||||
*** Time and Date configuration ***
|
||||
===================================
|
||||
[..]
|
||||
(+) To configure the RTC Calendar (Time and Date) use the HAL_RTC_SetTime()
|
||||
and HAL_RTC_SetDate() functions.
|
||||
(+) To read the RTC Calendar, use the HAL_RTC_GetTime() and HAL_RTC_GetDate() functions.
|
||||
|
||||
*** Alarm configuration ***
|
||||
===========================
|
||||
[..]
|
||||
(+) To configure the RTC Alarm use the HAL_RTC_SetAlarm() function.
|
||||
You can also configure the RTC Alarm with interrupt mode using the HAL_RTC_SetAlarm_IT() function.
|
||||
(+) To read the RTC Alarm, use the HAL_RTC_GetAlarm() function.
|
||||
|
||||
##### WARNING: Drivers Restrictions #####
|
||||
==================================================================
|
||||
[..] RTC version used on PY32F0xx families is version V1. All the features supported by V2
|
||||
(other families) will be not supported on F1.
|
||||
[..] As on V2, main RTC features are managed by HW. But on F1, date feature is completely
|
||||
managed by SW.
|
||||
[..] Then, there are some restrictions compared to other families:
|
||||
(+) Only format 24 hours supported in HAL (format 12 hours not supported)
|
||||
(+) Date is saved in SRAM. Then, when MCU is in STOP or STANDBY mode, date will be lost.
|
||||
User should implement a way to save date before entering in low power mode (an
|
||||
example is provided with firmware package based on backup registers)
|
||||
(+) Date is automatically updated each time a HAL_RTC_GetTime or HAL_RTC_GetDate is called.
|
||||
(+) Alarm detection is limited to 1 day. It will expire only 1 time (no alarm repetition, need
|
||||
to program a new alarm)
|
||||
|
||||
##### Backup Domain Operating Condition #####
|
||||
==============================================================================
|
||||
[..] The real-time clock (RTC) and the RTC backup registers can be powered
|
||||
from the VBAT voltage when the main VDD supply is powered off.
|
||||
To retain the content of the RTC backup registers and supply the RTC
|
||||
when VDD is turned off, VBAT pin can be connected to an optional
|
||||
standby voltage supplied by a battery or by another source.
|
||||
|
||||
[..] To allow the RTC operating even when the main digital supply (VDD) is turned
|
||||
off, the VBAT pin powers the following blocks:
|
||||
(#) The RTC
|
||||
(#) The LSE oscillator
|
||||
(#) The backup SRAM when the low power backup regulator is enabled
|
||||
(#) PC13 to PC15 I/Os, plus PI8 I/O (when available)
|
||||
|
||||
[..] When the backup domain is supplied by VDD (analog switch connected to VDD),
|
||||
the following pins are available:
|
||||
(+) PC13 can be used as a Tamper pin
|
||||
|
||||
[..] When the backup domain is supplied by VBAT (analog switch connected to VBAT
|
||||
because VDD is not present), the following pins are available:
|
||||
(+) PC13 can be used as the Tamper pin
|
||||
|
||||
##### Backup Domain Reset #####
|
||||
==================================================================
|
||||
[..] The backup domain reset sets all RTC registers and the RCC_BDCR register
|
||||
to their reset values.
|
||||
[..] A backup domain reset is generated when one of the following events occurs:
|
||||
(#) Software reset, triggered by setting the BDRST bit in the
|
||||
RCC Backup domain control register (RCC_BDCR).
|
||||
(#) VDD or VBAT power on, if both supplies have previously been powered off.
|
||||
(#) Tamper detection event resets all data backup registers.
|
||||
|
||||
##### Backup Domain Access #####
|
||||
==================================================================
|
||||
[..] After reset, the backup domain (RTC registers, RTC backup data
|
||||
registers and backup SRAM) is protected against possible unwanted write
|
||||
accesses.
|
||||
[..] To enable access to the RTC Domain and RTC registers, proceed as follows:
|
||||
(+) Call the function HAL_RCCEx_PeriphCLKConfig in using RCC_PERIPHCLK_RTC for
|
||||
PeriphClockSelection and select RTCClockSelection (LSE, LSI or HSE)
|
||||
(+) Enable the BKP clock in using __HAL_RCC_BKP_CLK_ENABLE()
|
||||
|
||||
##### RTC and low power modes #####
|
||||
==================================================================
|
||||
[..] The MCU can be woken up from a low power mode by an RTC alternate
|
||||
function.
|
||||
[..] The RTC alternate functions are the RTC alarms (Alarm A),
|
||||
and RTC tamper event detection.
|
||||
These RTC alternate functions can wake up the system from the Stop and
|
||||
Standby low power modes.
|
||||
[..] The system can also wake up from low power modes without depending
|
||||
on an external interrupt (Auto-wakeup mode), by using the RTC alarm.
|
||||
|
||||
*** Callback registration ***
|
||||
=============================================
|
||||
[..]
|
||||
The compilation define USE_HAL_RTC_REGISTER_CALLBACKS when set to 1
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
Use Function @ref HAL_RTC_RegisterCallback() to register an interrupt callback.
|
||||
|
||||
[..]
|
||||
Function @ref HAL_RTC_RegisterCallback() allows to register following callbacks:
|
||||
(+) AlarmAEventCallback : RTC Alarm A Event callback.
|
||||
(+) MspInitCallback : RTC MspInit callback.
|
||||
(+) MspDeInitCallback : RTC MspDeInit callback.
|
||||
[..]
|
||||
This function takes as parameters the HAL peripheral handle, the Callback ID
|
||||
and a pointer to the user callback function.
|
||||
|
||||
[..]
|
||||
Use function @ref HAL_RTC_UnRegisterCallback() to reset a callback to the default
|
||||
weak function.
|
||||
@ref HAL_RTC_UnRegisterCallback() takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
This function allows to reset following callbacks:
|
||||
(+) AlarmAEventCallback : RTC Alarm A Event callback.
|
||||
(+) MspInitCallback : RTC MspInit callback.
|
||||
(+) MspDeInitCallback : RTC MspDeInit callback.
|
||||
[..]
|
||||
By default, after the @ref HAL_RTC_Init() and when the state is HAL_RTC_STATE_RESET,
|
||||
all callbacks are set to the corresponding weak functions :
|
||||
example @ref AlarmAEventCallback().
|
||||
Exception done for MspInit and MspDeInit callbacks that are reset to the legacy weak function
|
||||
in the @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit() only when these callbacks are null
|
||||
(not registered beforehand).
|
||||
If not, MspInit or MspDeInit are not null, @ref HAL_RTC_Init()/@ref HAL_RTC_DeInit()
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
|
||||
[..]
|
||||
Callbacks can be registered/unregistered in HAL_RTC_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit that can be registered/unregistered
|
||||
in HAL_RTC_STATE_READY or HAL_RTC_STATE_RESET state,
|
||||
thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
|
||||
In that case first register the MspInit/MspDeInit user callbacks
|
||||
using @ref HAL_RTC_RegisterCallback() before calling @ref HAL_RTC_DeInit()
|
||||
or @ref HAL_RTC_Init() function.
|
||||
[..]
|
||||
When The compilation define USE_HAL_RTC_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available and all callbacks
|
||||
are set to the corresponding weak functions.
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 RTC RTC
|
||||
* @brief RTC HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup RTC_Private_Constants RTC Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define RTC_ALARM_RESETVALUE_REGISTER (uint16_t)0xFFFF
|
||||
#define RTC_ALARM_RESETVALUE 0xFFFFFFFFU
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/** @defgroup RTC_Private_Macros RTC Private Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup RTC_Private_Functions RTC Private Functions
|
||||
* @{
|
||||
*/
|
||||
static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc);
|
||||
static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter);
|
||||
static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc);
|
||||
static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter);
|
||||
static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc);
|
||||
static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc);
|
||||
static uint8_t RTC_ByteToBcd2(uint8_t Value);
|
||||
static uint8_t RTC_Bcd2ToByte(uint8_t Value);
|
||||
static uint8_t RTC_IsLeapYear(uint16_t nYear);
|
||||
static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed);
|
||||
static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup RTC_Exported_Functions RTC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to initialize and configure the
|
||||
RTC Prescaler (Asynchronous), disable RTC registers Write protection,
|
||||
enter and exit the RTC initialization mode,
|
||||
RTC registers synchronization check and reference clock detection enable.
|
||||
(#) The RTC Prescaler should be programmed to generate the RTC 1Hz time base.
|
||||
(#) All RTC registers are Write protected. Writing to the RTC registers
|
||||
is enabled by setting the CNF bit in the RTC_CRL register.
|
||||
(#) To read the calendar after wakeup from low power modes (Standby or Stop)
|
||||
the software must first wait for the RSF bit (Register Synchronized Flag)
|
||||
in the RTC_CRL register to be set by hardware.
|
||||
The HAL_RTC_WaitForSynchro() function implements the above software
|
||||
sequence (RSF clear and RSF check).
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the RTC peripheral
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint32_t prescaler = 0U;
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
|
||||
assert_param(IS_RTC_CALIB_OUTPUT(hrtc->Init.OutPut));
|
||||
assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
|
||||
|
||||
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
|
||||
if (hrtc->State == HAL_RTC_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hrtc->Lock = HAL_UNLOCKED;
|
||||
|
||||
hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
|
||||
|
||||
if (hrtc->MspInitCallback == NULL)
|
||||
{
|
||||
hrtc->MspInitCallback = HAL_RTC_MspInit;
|
||||
}
|
||||
/* Init the low level hardware */
|
||||
hrtc->MspInitCallback(hrtc);
|
||||
|
||||
if (hrtc->MspDeInitCallback == NULL)
|
||||
{
|
||||
hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (hrtc->State == HAL_RTC_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hrtc->Lock = HAL_UNLOCKED;
|
||||
|
||||
/* Initialize RTC MSP */
|
||||
HAL_RTC_MspInit(hrtc);
|
||||
}
|
||||
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */
|
||||
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Waiting for synchro */
|
||||
if (HAL_RTC_WaitForSynchro(hrtc) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (RTC_EnterInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear Flags Bits */
|
||||
CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_OW | RTC_FLAG_ALRAF | RTC_FLAG_SEC));
|
||||
|
||||
/* Set the signal which will be routed to RTC Tamper pin*/
|
||||
MODIFY_REG(hrtc->Instance->BKP_RTCCR, (BKP_RTCCR_CCO | BKP_RTCCR_ASOE | BKP_RTCCR_ASOS), hrtc->Init.OutPut);
|
||||
|
||||
if (hrtc->Init.AsynchPrediv != RTC_AUTO_1_SECOND)
|
||||
{
|
||||
/* RTC Prescaler provided directly by end-user*/
|
||||
prescaler = hrtc->Init.AsynchPrediv;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RTC Prescaler will be automatically calculated to get 1 second timebase */
|
||||
/* Get the RTCCLK frequency */
|
||||
prescaler = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_RTC);
|
||||
|
||||
/* Check that RTC clock is enabled*/
|
||||
if (prescaler == 0U)
|
||||
{
|
||||
/* Should not happen. Frequency is not available*/
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* RTC period = RTCCLK/(RTC_PR + 1) */
|
||||
prescaler = prescaler - 1U;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the RTC_PRLH / RTC_PRLL */
|
||||
MODIFY_REG(hrtc->Instance->PRLH, RTC_PRLH_PRL, (prescaler >> 16U));
|
||||
MODIFY_REG(hrtc->Instance->PRLL, RTC_PRLL_PRL, (prescaler & RTC_PRLL_PRL));
|
||||
|
||||
/* Wait for synchro */
|
||||
if (RTC_ExitInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Initialize date to 1st of January 2000 */
|
||||
hrtc->DateToUpdate.Year = 0x00U;
|
||||
hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
|
||||
hrtc->DateToUpdate.Date = 0x01U;
|
||||
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the RTC peripheral
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @note This function does not reset the RTC Backup Data registers.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_DeInit(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(hrtc->Instance));
|
||||
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (RTC_EnterInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_REG(hrtc->Instance->CNTL);
|
||||
CLEAR_REG(hrtc->Instance->CNTH);
|
||||
WRITE_REG(hrtc->Instance->PRLL, 0x00008000U);
|
||||
CLEAR_REG(hrtc->Instance->PRLH);
|
||||
|
||||
/* Reset All CRH/CRL bits */
|
||||
CLEAR_REG(hrtc->Instance->CRH);
|
||||
CLEAR_REG(hrtc->Instance->CRL);
|
||||
|
||||
if (RTC_ExitInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for synchro*/
|
||||
HAL_RTC_WaitForSynchro(hrtc);
|
||||
|
||||
/* Clear RSF flag */
|
||||
CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
|
||||
|
||||
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
|
||||
if (hrtc->MspDeInitCallback == NULL)
|
||||
{
|
||||
hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
|
||||
}
|
||||
|
||||
/* DeInit the low level hardware: CLOCK, NVIC.*/
|
||||
hrtc->MspDeInitCallback(hrtc);
|
||||
|
||||
#else
|
||||
/* De-Initialize RTC MSP */
|
||||
HAL_RTC_MspDeInit(hrtc);
|
||||
#endif /* (USE_HAL_RTC_REGISTER_CALLBACKS) */
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User RTC Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param hrtc RTC handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
|
||||
* @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID
|
||||
* @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
|
||||
* @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_RegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID, pRTC_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
if (HAL_RTC_STATE_READY == hrtc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_RTC_ALARM_A_EVENT_CB_ID :
|
||||
hrtc->AlarmAEventCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_RTC_TAMPER1_EVENT_CB_ID :
|
||||
hrtc->Tamper1EventCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPINIT_CB_ID :
|
||||
hrtc->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPDEINIT_CB_ID :
|
||||
hrtc->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_RTC_STATE_RESET == hrtc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_RTC_MSPINIT_CB_ID :
|
||||
hrtc->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPDEINIT_CB_ID :
|
||||
hrtc->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister an RTC Callback
|
||||
* RTC callabck is redirected to the weak predefined callback
|
||||
* @param hrtc RTC handle
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_RTC_ALARM_A_EVENT_CB_ID Alarm A Event Callback ID
|
||||
* @arg @ref HAL_RTC_TAMPER1_EVENT_CB_ID Tamper 1 Callback ID
|
||||
* @arg @ref HAL_RTC_MSPINIT_CB_ID Msp Init callback ID
|
||||
* @arg @ref HAL_RTC_MSPDEINIT_CB_ID Msp DeInit callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_UnRegisterCallback(RTC_HandleTypeDef *hrtc, HAL_RTC_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
if (HAL_RTC_STATE_READY == hrtc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_RTC_ALARM_A_EVENT_CB_ID :
|
||||
hrtc->AlarmAEventCallback = HAL_RTC_AlarmAEventCallback; /* Legacy weak AlarmAEventCallback */
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPINIT_CB_ID :
|
||||
hrtc->MspInitCallback = HAL_RTC_MspInit;
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPDEINIT_CB_ID :
|
||||
hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_RTC_STATE_RESET == hrtc->State)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_RTC_MSPINIT_CB_ID :
|
||||
hrtc->MspInitCallback = HAL_RTC_MspInit;
|
||||
break;
|
||||
|
||||
case HAL_RTC_MSPDEINIT_CB_ID :
|
||||
hrtc->MspDeInitCallback = HAL_RTC_MspDeInit;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @brief Initializes the RTC MSP.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_RTC_MspInit(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hrtc);
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_RTC_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the RTC MSP.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_RTC_MspDeInit(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hrtc);
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_RTC_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Exported_Functions_Group2 Time and Date functions
|
||||
* @brief RTC Time and Date functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### RTC Time and Date functions #####
|
||||
===============================================================================
|
||||
|
||||
[..] This section provides functions allowing to configure Time and Date features
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets RTC current time.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sTime: Pointer to Time structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_SetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_time = 0U, counter_alarm = 0U;
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sTime == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
if (Format == RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(sTime->Hours));
|
||||
assert_param(IS_RTC_MINUTES(sTime->Minutes));
|
||||
assert_param(IS_RTC_SECONDS(sTime->Seconds));
|
||||
|
||||
counter_time = (uint32_t)(((uint32_t)sTime->Hours * 3600U) + \
|
||||
((uint32_t)sTime->Minutes * 60U) + \
|
||||
((uint32_t)sTime->Seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sTime->Hours)));
|
||||
assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sTime->Minutes)));
|
||||
assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sTime->Seconds)));
|
||||
|
||||
counter_time = (((uint32_t)(RTC_Bcd2ToByte(sTime->Hours)) * 3600U) + \
|
||||
((uint32_t)(RTC_Bcd2ToByte(sTime->Minutes)) * 60U) + \
|
||||
((uint32_t)(RTC_Bcd2ToByte(sTime->Seconds))));
|
||||
}
|
||||
|
||||
/* Write time counter in RTC registers */
|
||||
if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear Second and overflow flags */
|
||||
CLEAR_BIT(hrtc->Instance->CRL, (RTC_FLAG_SEC | RTC_FLAG_OW));
|
||||
|
||||
/* Read current Alarm counter in RTC registers */
|
||||
counter_alarm = RTC_ReadAlarmCounter(hrtc);
|
||||
|
||||
/* Set again alarm to match with new time if enabled */
|
||||
if (counter_alarm != RTC_ALARM_RESETVALUE)
|
||||
{
|
||||
if (counter_alarm < counter_time)
|
||||
{
|
||||
/* Add 1 day to alarm counter*/
|
||||
counter_alarm += (uint32_t)(24U * 3600U);
|
||||
|
||||
/* Write new Alarm counter in RTC registers */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets RTC current time.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sTime: Pointer to Time structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_time = 0U, counter_alarm = 0U, days_elapsed = 0U, hours = 0U;
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sTime == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Check if counter overflow occurred */
|
||||
if (__HAL_RTC_OVERFLOW_GET_FLAG(hrtc, RTC_FLAG_OW))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Read the time counter*/
|
||||
counter_time = RTC_ReadTimeCounter(hrtc);
|
||||
|
||||
/* Fill the structure fields with the read parameters */
|
||||
hours = counter_time / 3600U;
|
||||
sTime->Minutes = (uint8_t)((counter_time % 3600U) / 60U);
|
||||
sTime->Seconds = (uint8_t)((counter_time % 3600U) % 60U);
|
||||
|
||||
if (hours >= 24U)
|
||||
{
|
||||
/* Get number of days elapsed from last calculation */
|
||||
days_elapsed = (hours / 24U);
|
||||
|
||||
/* Set Hours in RTC_TimeTypeDef structure*/
|
||||
sTime->Hours = (hours % 24U);
|
||||
|
||||
/* Read Alarm counter in RTC registers */
|
||||
counter_alarm = RTC_ReadAlarmCounter(hrtc);
|
||||
|
||||
/* Calculate remaining time to reach alarm (only if set and not yet expired)*/
|
||||
if ((counter_alarm != RTC_ALARM_RESETVALUE) && (counter_alarm > counter_time))
|
||||
{
|
||||
counter_alarm -= counter_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* In case of counter_alarm < counter_time */
|
||||
/* Alarm expiration already occurred but alarm not deactivated */
|
||||
counter_alarm = RTC_ALARM_RESETVALUE;
|
||||
}
|
||||
|
||||
/* Set updated time in decreasing counter by number of days elapsed */
|
||||
counter_time -= (days_elapsed * 24U * 3600U);
|
||||
|
||||
/* Write time counter in RTC registers */
|
||||
if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Set updated alarm to be set */
|
||||
if (counter_alarm != RTC_ALARM_RESETVALUE)
|
||||
{
|
||||
counter_alarm += counter_time;
|
||||
|
||||
/* Write time counter in RTC registers */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Alarm already occurred. Set it to reset values to avoid unexpected expiration */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update date */
|
||||
RTC_DateUpdate(hrtc, days_elapsed);
|
||||
}
|
||||
else
|
||||
{
|
||||
sTime->Hours = hours;
|
||||
}
|
||||
|
||||
/* Check the input parameters format */
|
||||
if (Format != RTC_FORMAT_BIN)
|
||||
{
|
||||
/* Convert the time structure parameters to BCD format */
|
||||
sTime->Hours = (uint8_t)RTC_ByteToBcd2(sTime->Hours);
|
||||
sTime->Minutes = (uint8_t)RTC_ByteToBcd2(sTime->Minutes);
|
||||
sTime->Seconds = (uint8_t)RTC_ByteToBcd2(sTime->Seconds);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets RTC current date.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sDate: Pointer to date structure
|
||||
* @param Format: specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sDate == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
if (Format == RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_RTC_YEAR(sDate->Year));
|
||||
assert_param(IS_RTC_MONTH(sDate->Month));
|
||||
assert_param(IS_RTC_DATE(sDate->Date));
|
||||
|
||||
/* Change the current date */
|
||||
hrtc->DateToUpdate.Year = sDate->Year;
|
||||
hrtc->DateToUpdate.Month = sDate->Month;
|
||||
hrtc->DateToUpdate.Date = sDate->Date;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
|
||||
assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
|
||||
assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
|
||||
|
||||
/* Change the current date */
|
||||
hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
|
||||
hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
|
||||
hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
|
||||
}
|
||||
|
||||
/* WeekDay set by user can be ignored because automatically calculated */
|
||||
hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
|
||||
sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
|
||||
|
||||
/* Reset time to be aligned on the same day */
|
||||
/* Read the time counter*/
|
||||
counter_time = RTC_ReadTimeCounter(hrtc);
|
||||
|
||||
/* Fill the structure fields with the read parameters */
|
||||
hours = counter_time / 3600U;
|
||||
if (hours > 24U)
|
||||
{
|
||||
/* Set updated time in decreasing counter by number of days elapsed */
|
||||
counter_time -= ((hours / 24U) * 24U * 3600U);
|
||||
/* Write time counter in RTC registers */
|
||||
if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Read current Alarm counter in RTC registers */
|
||||
counter_alarm = RTC_ReadAlarmCounter(hrtc);
|
||||
|
||||
/* Set again alarm to match with new time if enabled */
|
||||
if (counter_alarm != RTC_ALARM_RESETVALUE)
|
||||
{
|
||||
if (counter_alarm < counter_time)
|
||||
{
|
||||
/* Add 1 day to alarm counter*/
|
||||
counter_alarm += (uint32_t)(24U * 3600U);
|
||||
|
||||
/* Write new Alarm counter in RTC registers */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_READY ;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets RTC current date.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sDate: Pointer to Date structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
|
||||
{
|
||||
RTC_TimeTypeDef stime = {0U};
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sDate == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
|
||||
if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Fill the structure fields with the read parameters */
|
||||
sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
|
||||
sDate->Year = hrtc->DateToUpdate.Year;
|
||||
sDate->Month = hrtc->DateToUpdate.Month;
|
||||
sDate->Date = hrtc->DateToUpdate.Date;
|
||||
|
||||
/* Check the input parameters format */
|
||||
if (Format != RTC_FORMAT_BIN)
|
||||
{
|
||||
/* Convert the date structure parameters to BCD format */
|
||||
sDate->Year = (uint8_t)RTC_ByteToBcd2(sDate->Year);
|
||||
sDate->Month = (uint8_t)RTC_ByteToBcd2(sDate->Month);
|
||||
sDate->Date = (uint8_t)RTC_ByteToBcd2(sDate->Date);
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Exported_Functions_Group3 Alarm functions
|
||||
* @brief RTC Alarm functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### RTC Alarm functions #####
|
||||
===============================================================================
|
||||
|
||||
[..] This section provides functions allowing to configure Alarm feature
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets the specified RTC Alarm.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sAlarm: Pointer to Alarm structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_SetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_alarm = 0U, counter_time;
|
||||
RTC_TimeTypeDef stime = {0U};
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sAlarm == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
|
||||
if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Convert time in seconds */
|
||||
counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
|
||||
((uint32_t)stime.Minutes * 60U) + \
|
||||
((uint32_t)stime.Seconds));
|
||||
|
||||
if (Format == RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
|
||||
assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
|
||||
assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
|
||||
|
||||
counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
|
||||
((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
|
||||
((uint32_t)sAlarm->AlarmTime.Seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
|
||||
assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
|
||||
assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
|
||||
|
||||
counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
|
||||
((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
|
||||
((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
|
||||
}
|
||||
|
||||
/* Check that requested alarm should expire in the same day (otherwise add 1 day) */
|
||||
if (counter_alarm < counter_time)
|
||||
{
|
||||
/* Add 1 day to alarm counter*/
|
||||
counter_alarm += (uint32_t)(24U * 3600U);
|
||||
}
|
||||
|
||||
/* Write Alarm counter in RTC registers */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the specified RTC Alarm with Interrupt
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sAlarm: Pointer to Alarm structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_alarm = 0U, counter_time;
|
||||
RTC_TimeTypeDef stime = {0U};
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sAlarm == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
|
||||
if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Convert time in seconds */
|
||||
counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600U) + \
|
||||
((uint32_t)stime.Minutes * 60U) + \
|
||||
((uint32_t)stime.Seconds));
|
||||
|
||||
if (Format == RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(sAlarm->AlarmTime.Hours));
|
||||
assert_param(IS_RTC_MINUTES(sAlarm->AlarmTime.Minutes));
|
||||
assert_param(IS_RTC_SECONDS(sAlarm->AlarmTime.Seconds));
|
||||
|
||||
counter_alarm = (uint32_t)(((uint32_t)sAlarm->AlarmTime.Hours * 3600U) + \
|
||||
((uint32_t)sAlarm->AlarmTime.Minutes * 60U) + \
|
||||
((uint32_t)sAlarm->AlarmTime.Seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_RTC_HOUR24(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)));
|
||||
assert_param(IS_RTC_MINUTES(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)));
|
||||
assert_param(IS_RTC_SECONDS(RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
|
||||
|
||||
counter_alarm = (((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Hours)) * 3600U) + \
|
||||
((uint32_t)(RTC_Bcd2ToByte(sAlarm->AlarmTime.Minutes)) * 60U) + \
|
||||
((uint32_t)RTC_Bcd2ToByte(sAlarm->AlarmTime.Seconds)));
|
||||
}
|
||||
|
||||
/* Check that requested alarm should expire in the same day (otherwise add 1 day) */
|
||||
if (counter_alarm < counter_time)
|
||||
{
|
||||
/* Add 1 day to alarm counter*/
|
||||
counter_alarm += (uint32_t)(24U * 3600U);
|
||||
}
|
||||
|
||||
/* Write alarm counter in RTC registers */
|
||||
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear flag alarm A */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
|
||||
/* Configure the Alarm interrupt */
|
||||
__HAL_RTC_ALARM_ENABLE_IT(hrtc, RTC_IT_ALRA);
|
||||
|
||||
/* RTC Alarm Interrupt Configuration: EXTI configuration */
|
||||
__HAL_RTC_ALARM_EXTI_ENABLE_IT();
|
||||
|
||||
__HAL_RTC_ALARM_EXTI_ENABLE_RISING_EDGE();
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the RTC Alarm value and masks.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param sAlarm: Pointer to Date structure
|
||||
* @param Format: Specifies the format of the entered parameters.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg RTC_FORMAT_BIN: Binary data format
|
||||
* @arg RTC_FORMAT_BCD: BCD data format
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_GetAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format)
|
||||
{
|
||||
uint32_t counter_alarm = 0U;
|
||||
|
||||
/* Check input parameters */
|
||||
if ((hrtc == NULL) || (sAlarm == NULL))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_FORMAT(Format));
|
||||
|
||||
/* Read Alarm counter in RTC registers */
|
||||
counter_alarm = RTC_ReadAlarmCounter(hrtc);
|
||||
|
||||
/* Fill the structure with the read parameters */
|
||||
/* Set hours in a day range (between 0 to 24)*/
|
||||
sAlarm->AlarmTime.Hours = (uint32_t)((counter_alarm / 3600U) % 24U);
|
||||
sAlarm->AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600U) / 60U);
|
||||
sAlarm->AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600U) % 60U);
|
||||
|
||||
if (Format != RTC_FORMAT_BIN)
|
||||
{
|
||||
sAlarm->AlarmTime.Hours = RTC_ByteToBcd2(sAlarm->AlarmTime.Hours);
|
||||
sAlarm->AlarmTime.Minutes = RTC_ByteToBcd2(sAlarm->AlarmTime.Minutes);
|
||||
sAlarm->AlarmTime.Seconds = RTC_ByteToBcd2(sAlarm->AlarmTime.Seconds);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactive the specified RTC Alarm
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_DeactivateAlarm(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* In case of interrupt mode is used, the interrupt source must disabled */
|
||||
__HAL_RTC_ALARM_DISABLE_IT(hrtc, RTC_IT_ALRA);
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (RTC_EnterInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
/* Set RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear flag alarm A */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
|
||||
/* Set to default values ALRH & ALRL registers */
|
||||
WRITE_REG(hrtc->Instance->ALRH, RTC_ALARM_RESETVALUE_REGISTER);
|
||||
WRITE_REG(hrtc->Instance->ALRL, RTC_ALARM_RESETVALUE_REGISTER);
|
||||
|
||||
/* RTC Alarm Interrupt Configuration: Disable EXTI configuration */
|
||||
__HAL_RTC_ALARM_EXTI_DISABLE_IT();
|
||||
|
||||
/* Wait for synchro */
|
||||
if (RTC_ExitInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Alarm interrupt request.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RTC_AlarmIRQHandler(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
|
||||
{
|
||||
/* Get the status of the Interrupt */
|
||||
if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
|
||||
{
|
||||
/* AlarmA callback */
|
||||
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
|
||||
hrtc->AlarmAEventCallback(hrtc);
|
||||
#else
|
||||
HAL_RTC_AlarmAEventCallback(hrtc);
|
||||
#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
|
||||
|
||||
/* Clear the Alarm interrupt pending bit */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the EXTI's line Flag for RTC Alarm */
|
||||
__HAL_RTC_ALARM_EXTI_CLEAR_FLAG();
|
||||
|
||||
/* Change RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Alarm A callback.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hrtc);
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_RTC_AlarmAEventCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles AlarmA Polling request.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param Timeout: Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_PollForAlarmAEvent(RTC_HandleTypeDef *hrtc, uint32_t Timeout)
|
||||
{
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) == RESET)
|
||||
{
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if ((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
|
||||
{
|
||||
hrtc->State = HAL_RTC_STATE_TIMEOUT;
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the Alarm interrupt pending bit */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
|
||||
/* Change RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Exported_Functions_Group4 Peripheral State functions
|
||||
* @brief Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Get RTC state
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Returns the RTC state.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_RTCStateTypeDef HAL_RTC_GetState(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
return hrtc->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTC_Exported_Functions_Group5 Peripheral Control functions
|
||||
* @brief Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Wait for RTC Time and Date Synchronization
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Waits until the RTC registers (RTC_CNT, RTC_ALR and RTC_PRL)
|
||||
* are synchronized with RTC APB clock.
|
||||
* @note This function must be called before any read operation after an APB reset
|
||||
* or an APB clock stop.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Clear RSF flag */
|
||||
CLEAR_BIT(hrtc->Instance->CRL, RTC_FLAG_RSF);
|
||||
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait the registers to be synchronised */
|
||||
while ((hrtc->Instance->CRL & RTC_FLAG_RSF) == (uint32_t)RESET)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RTC_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read the time counter available in RTC_CNT registers.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval Time counter
|
||||
*/
|
||||
static uint32_t RTC_ReadTimeCounter(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint16_t high1 = 0U, high2 = 0U, low = 0U;
|
||||
uint32_t timecounter = 0U;
|
||||
|
||||
high1 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
|
||||
low = READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT);
|
||||
high2 = READ_REG(hrtc->Instance->CNTH & RTC_CNTH_RTC_CNT);
|
||||
|
||||
if (high1 != high2)
|
||||
{
|
||||
/* In this case the counter roll over during reading of CNTL and CNTH registers,
|
||||
read again CNTL register then return the counter value */
|
||||
timecounter = (((uint32_t) high2 << 16U) | READ_REG(hrtc->Instance->CNTL & RTC_CNTL_RTC_CNT));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No counter roll over during reading of CNTL and CNTH registers, counter
|
||||
value is equal to first value of CNTL and CNTH */
|
||||
timecounter = (((uint32_t) high1 << 16U) | low);
|
||||
}
|
||||
|
||||
return timecounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the time counter in RTC_CNT registers.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param TimeCounter: Counter to write in RTC_CNT registers
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RTC_WriteTimeCounter(RTC_HandleTypeDef *hrtc, uint32_t TimeCounter)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (RTC_EnterInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set RTC COUNTER MSB word */
|
||||
WRITE_REG(hrtc->Instance->CNTH, (TimeCounter >> 16U));
|
||||
/* Set RTC COUNTER LSB word */
|
||||
WRITE_REG(hrtc->Instance->CNTL, (TimeCounter & RTC_CNTL_RTC_CNT));
|
||||
|
||||
/* Wait for synchro */
|
||||
if (RTC_ExitInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read the time counter available in RTC_ALR registers.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval Time counter
|
||||
*/
|
||||
static uint32_t RTC_ReadAlarmCounter(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint16_t high1 = 0U, low = 0U;
|
||||
|
||||
high1 = READ_REG(hrtc->Instance->ALRH & RTC_CNTH_RTC_CNT);
|
||||
low = READ_REG(hrtc->Instance->ALRL & RTC_CNTL_RTC_CNT);
|
||||
|
||||
return (((uint32_t) high1 << 16U) | low);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write the time counter in RTC_ALR registers.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param AlarmCounter: Counter to write in RTC_ALR registers
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef *hrtc, uint32_t AlarmCounter)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (RTC_EnterInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set RTC COUNTER MSB word */
|
||||
WRITE_REG(hrtc->Instance->ALRH, (AlarmCounter >> 16U));
|
||||
/* Set RTC COUNTER LSB word */
|
||||
WRITE_REG(hrtc->Instance->ALRL, (AlarmCounter & RTC_ALRL_RTC_ALR));
|
||||
|
||||
/* Wait for synchro */
|
||||
if (RTC_ExitInitMode(hrtc) != HAL_OK)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters the RTC Initialization mode.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
tickstart = HAL_GetTick();
|
||||
/* Wait till RTC is in INIT state and if Time out is reached exit */
|
||||
while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the write protection for RTC registers */
|
||||
__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
|
||||
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exit the RTC Initialization mode.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef RTC_ExitInitMode(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Disable the write protection for RTC registers */
|
||||
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
|
||||
|
||||
tickstart = HAL_GetTick();
|
||||
/* Wait till RTC is in NOINIT state and if Time out is reached exit */
|
||||
while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == RTC_CRL_RTOFF)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RTC_RTOFF_RESET_TIMEOUT_VALUE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tickstart = HAL_GetTick();
|
||||
/* Wait till RTC is in INIT state and if Time out is reached exit */
|
||||
while ((hrtc->Instance->CRL & RTC_CRL_RTOFF) == (uint32_t)RESET)
|
||||
{
|
||||
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts a 2 digit decimal to BCD format.
|
||||
* @param Value: Byte to be converted
|
||||
* @retval Converted byte
|
||||
*/
|
||||
static uint8_t RTC_ByteToBcd2(uint8_t Value)
|
||||
{
|
||||
uint32_t bcdhigh = 0U;
|
||||
|
||||
while (Value >= 10U)
|
||||
{
|
||||
bcdhigh++;
|
||||
Value -= 10U;
|
||||
}
|
||||
|
||||
return ((uint8_t)(bcdhigh << 4U) | Value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts from 2 digit BCD to Binary.
|
||||
* @param Value: BCD value to be converted
|
||||
* @retval Converted word
|
||||
*/
|
||||
static uint8_t RTC_Bcd2ToByte(uint8_t Value)
|
||||
{
|
||||
uint32_t tmp = 0U;
|
||||
tmp = ((uint8_t)(Value & (uint8_t)0xF0) >> (uint8_t)0x4) * 10U;
|
||||
return (tmp + (Value & (uint8_t)0x0F));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates date when time is 23:59:59.
|
||||
* @param hrtc pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @param DayElapsed: Number of days elapsed from last date update
|
||||
* @retval None
|
||||
*/
|
||||
static void RTC_DateUpdate(RTC_HandleTypeDef *hrtc, uint32_t DayElapsed)
|
||||
{
|
||||
uint32_t year = 0U, month = 0U, day = 0U;
|
||||
uint32_t loop = 0U;
|
||||
|
||||
/* Get the current year*/
|
||||
year = hrtc->DateToUpdate.Year;
|
||||
|
||||
/* Get the current month and day */
|
||||
month = hrtc->DateToUpdate.Month;
|
||||
day = hrtc->DateToUpdate.Date;
|
||||
|
||||
for (loop = 0U; loop < DayElapsed; loop++)
|
||||
{
|
||||
if ((month == 1U) || (month == 3U) || (month == 5U) || (month == 7U) || \
|
||||
(month == 8U) || (month == 10U) || (month == 12U))
|
||||
{
|
||||
if (day < 31U)
|
||||
{
|
||||
day++;
|
||||
}
|
||||
/* Date structure member: day = 31 */
|
||||
else
|
||||
{
|
||||
if (month != 12U)
|
||||
{
|
||||
month++;
|
||||
day = 1U;
|
||||
}
|
||||
/* Date structure member: day = 31 & month =12 */
|
||||
else
|
||||
{
|
||||
month = 1U;
|
||||
day = 1U;
|
||||
year++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((month == 4U) || (month == 6U) || (month == 9U) || (month == 11U))
|
||||
{
|
||||
if (day < 30U)
|
||||
{
|
||||
day++;
|
||||
}
|
||||
/* Date structure member: day = 30 */
|
||||
else
|
||||
{
|
||||
month++;
|
||||
day = 1U;
|
||||
}
|
||||
}
|
||||
else if (month == 2U)
|
||||
{
|
||||
if (day < 28U)
|
||||
{
|
||||
day++;
|
||||
}
|
||||
else if (day == 28U)
|
||||
{
|
||||
/* Leap year */
|
||||
if (RTC_IsLeapYear(year))
|
||||
{
|
||||
day++;
|
||||
}
|
||||
else
|
||||
{
|
||||
month++;
|
||||
day = 1U;
|
||||
}
|
||||
}
|
||||
else if (day == 29U)
|
||||
{
|
||||
month++;
|
||||
day = 1U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Update year */
|
||||
hrtc->DateToUpdate.Year = year;
|
||||
|
||||
/* Update day and month */
|
||||
hrtc->DateToUpdate.Month = month;
|
||||
hrtc->DateToUpdate.Date = day;
|
||||
|
||||
/* Update day of the week */
|
||||
hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether the passed year is Leap or not.
|
||||
* @param nYear year to check
|
||||
* @retval 1: leap year
|
||||
* 0: not leap year
|
||||
*/
|
||||
static uint8_t RTC_IsLeapYear(uint16_t nYear)
|
||||
{
|
||||
if ((nYear % 4U) != 0U)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
|
||||
if ((nYear % 100U) != 0U)
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
|
||||
if ((nYear % 400U) == 0U)
|
||||
{
|
||||
return 1U;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Determines the week number, the day number and the week day number.
|
||||
* @param nYear year to check
|
||||
* @param nMonth Month to check
|
||||
* @param nDay Day to check
|
||||
* @note Day is calculated with hypothesis that year > 2000
|
||||
* @retval Value which can take one of the following parameters:
|
||||
* @arg RTC_WEEKDAY_MONDAY
|
||||
* @arg RTC_WEEKDAY_TUESDAY
|
||||
* @arg RTC_WEEKDAY_WEDNESDAY
|
||||
* @arg RTC_WEEKDAY_THURSDAY
|
||||
* @arg RTC_WEEKDAY_FRIDAY
|
||||
* @arg RTC_WEEKDAY_SATURDAY
|
||||
* @arg RTC_WEEKDAY_SUNDAY
|
||||
*/
|
||||
static uint8_t RTC_WeekDayNum(uint32_t nYear, uint8_t nMonth, uint8_t nDay)
|
||||
{
|
||||
uint32_t year = 0U, weekday = 0U;
|
||||
|
||||
year = 2000U + nYear;
|
||||
|
||||
if (nMonth < 3U)
|
||||
{
|
||||
/*D = { [(23 x month)/9] + day + 4 + year + [(year-1)/4] - [(year-1)/100] + [(year-1)/400] } mod 7*/
|
||||
weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + ((year - 1U) / 4U) - ((year - 1U) / 100U) + ((year - 1U) / 400U)) % 7U;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*D = { [(23 x month)/9] + day + 4 + year + [year/4] - [year/100] + [year/400] - 2 } mod 7*/
|
||||
weekday = (((23U * nMonth) / 9U) + nDay + 4U + year + (year / 4U) - (year / 100U) + (year / 400U) - 2U) % 7U;
|
||||
}
|
||||
|
||||
return (uint8_t)weekday;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
303
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rtc_ex.c
Normal file
303
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_rtc_ex.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_rtc_ex.c
|
||||
* @author MCU Application Team
|
||||
* @brief Extended RTC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Real Time Clock (RTC) Extension peripheral:
|
||||
* + RTC Tamper functions
|
||||
* + Extension Control functions
|
||||
* + Extension RTC features functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
|
||||
/** @defgroup RTCEx RTCEx
|
||||
* @brief RTC Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/** @defgroup RTCEx_Private_Macros RTCEx Private Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RTCEx_Exported_Functions RTCEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RTCEx_Exported_Functions_Group2 RTC Second functions
|
||||
* @brief RTC Second functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### RTC Second functions #####
|
||||
===============================================================================
|
||||
|
||||
[..] This section provides functions implementing second interupt handlers
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets Interrupt for second
|
||||
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTCEx_SetSecond_IT(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Enable Second interuption */
|
||||
__HAL_RTC_SECOND_ENABLE_IT(hrtc, RTC_IT_SEC);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deactivates Second.
|
||||
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTCEx_DeactivateSecond(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Deactivate Second interuption*/
|
||||
__HAL_RTC_SECOND_DISABLE_IT(hrtc, RTC_IT_SEC);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles second interrupt request.
|
||||
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RTCEx_RTCIRQHandler(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
|
||||
if (__HAL_RTC_SECOND_GET_IT_SOURCE(hrtc, RTC_IT_SEC))
|
||||
{
|
||||
/* Get the status of the Interrupt */
|
||||
if (__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_SEC))
|
||||
{
|
||||
/* Check if Overrun occurred */
|
||||
if (__HAL_RTC_SECOND_GET_FLAG(hrtc, RTC_FLAG_OW))
|
||||
{
|
||||
/* Second error callback */
|
||||
HAL_RTCEx_RTCEventErrorCallback(hrtc);
|
||||
|
||||
/* Clear flag Second */
|
||||
__HAL_RTC_OVERFLOW_CLEAR_FLAG(hrtc, RTC_FLAG_OW);
|
||||
|
||||
/* Change RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Second callback */
|
||||
HAL_RTCEx_RTCEventCallback(hrtc);
|
||||
|
||||
/* Change RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
}
|
||||
|
||||
/* Clear flag Second */
|
||||
__HAL_RTC_SECOND_CLEAR_FLAG(hrtc, RTC_FLAG_SEC);
|
||||
}
|
||||
}
|
||||
if (__HAL_RTC_ALARM_GET_IT_SOURCE(hrtc, RTC_IT_ALRA))
|
||||
{
|
||||
/* Get the status of the Interrupt */
|
||||
if (__HAL_RTC_ALARM_GET_FLAG(hrtc, RTC_FLAG_ALRAF) != (uint32_t)RESET)
|
||||
{
|
||||
/* AlarmA callback */
|
||||
#if (USE_HAL_RTC_REGISTER_CALLBACKS == 1)
|
||||
hrtc->AlarmAEventCallback(hrtc);
|
||||
#else
|
||||
HAL_RTC_AlarmAEventCallback(hrtc);
|
||||
#endif /* USE_HAL_RTC_REGISTER_CALLBACKS */
|
||||
|
||||
/* Clear the Alarm interrupt pending bit */
|
||||
__HAL_RTC_ALARM_CLEAR_FLAG(hrtc, RTC_FLAG_ALRAF);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Second event callback.
|
||||
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hrtc);
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_RTCEx_RTCEventCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Second event error callback.
|
||||
* @param hrtc: pointer to a RTC_HandleTypeDef structure that contains
|
||||
* the configuration information for RTC.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_RTCEx_RTCEventErrorCallback(RTC_HandleTypeDef *hrtc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hrtc);
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_RTCEx_RTCEventErrorCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RTCEx_Exported_Functions_Group3 Extended Peripheral Control functions
|
||||
* @brief Extended Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extension Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Writes a data in a specified RTC Backup data register
|
||||
(+) Read a data in a specified RTC Backup data register
|
||||
(+) Sets the Smooth calibration parameters.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets the Smooth calibration parameters.
|
||||
* @param hrtc: RTC handle
|
||||
* @param SmoothCalibPeriod: Not used (only present for compatibility with another families)
|
||||
* @param SmoothCalibPlusPulses: Not used (only present for compatibility with another families)
|
||||
* @param SmouthCalibMinusPulsesValue: specifies the RTC Clock Calibration value.
|
||||
* This parameter must be a number between 0 and 0x7F.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RTCEx_SetSmoothCalib(RTC_HandleTypeDef *hrtc, uint32_t SmoothCalibPeriod, uint32_t SmoothCalibPlusPulses, uint32_t SmouthCalibMinusPulsesValue)
|
||||
{
|
||||
/* Check input parameters */
|
||||
if (hrtc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(SmoothCalibPeriod);
|
||||
UNUSED(SmoothCalibPlusPulses);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_SMOOTH_CALIB_MINUS(SmouthCalibMinusPulsesValue));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(hrtc);
|
||||
|
||||
hrtc->State = HAL_RTC_STATE_BUSY;
|
||||
|
||||
/* Sets RTC Clock Calibration value.*/
|
||||
MODIFY_REG(RTC->BKP_RTCCR, BKP_RTCCR_CAL, SmouthCalibMinusPulsesValue);
|
||||
|
||||
/* Change RTC state */
|
||||
hrtc->State = HAL_RTC_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hrtc);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
|
||||
3729
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_spi.c
Normal file
3729
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_spi.c
Normal file
@@ -0,0 +1,3729 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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****/
|
||||
6791
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_tim.c
Normal file
6791
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_tim.c
Normal file
File diff suppressed because it is too large
Load Diff
1959
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_tim_ex.c
Normal file
1959
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_tim_ex.c
Normal file
@@ -0,0 +1,1959 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_tim_ex.c
|
||||
* @author MCU Application Team
|
||||
* @brief TIM HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Timer Extended peripheral:
|
||||
* + Time Hall Sensor Interface Initialization
|
||||
* + Time Hall Sensor Interface Start
|
||||
* + Time Complementary signal break and dead time configuration
|
||||
* + Time Master and Slave synchronization configuration
|
||||
* + Time OCRef clear configuration
|
||||
* + Timer remapping capabilities configuration
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### TIMER Extended features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The Timer Extended features include:
|
||||
(#) Complementary outputs with programmable dead-time for :
|
||||
(++) Output Compare
|
||||
(++) PWM generation (Edge and Center-aligned Mode)
|
||||
(++) One-pulse mode output
|
||||
(#) Synchronization circuit to control the timer with external signals and to
|
||||
interconnect several timers together.
|
||||
(#) Break input to put the timer output signals in reset state or in a known state.
|
||||
(#) Supports incremental (quadrature) encoder and hall-sensor circuitry for
|
||||
positioning purposes
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Initialize the TIM low level resources by implementing the following functions
|
||||
depending on the selected feature:
|
||||
(++) Hall Sensor output : HAL_TIMEx_HallSensor_MspInit()
|
||||
|
||||
(#) Initialize the TIM low level resources :
|
||||
(##) Enable the TIM interface clock using __HAL_RCC_TIMx_CLK_ENABLE();
|
||||
(##) TIM pins configuration
|
||||
(+++) Enable the clock for the TIM GPIOs using the following function:
|
||||
__HAL_RCC_GPIOx_CLK_ENABLE();
|
||||
(+++) Configure these TIM pins in Alternate function mode using HAL_GPIO_Init();
|
||||
|
||||
(#) The external Clock can be configured, if needed (the default clock is the
|
||||
internal clock from the APBx), using the following function:
|
||||
HAL_TIM_ConfigClockSource, the clock configuration should be done before
|
||||
any start function.
|
||||
|
||||
(#) Configure the TIM in the desired functioning mode using one of the
|
||||
initialization function of this driver:
|
||||
(++) HAL_TIMEx_HallSensor_Init() and HAL_TIMEx_ConfigCommutEvent(): to use the
|
||||
Timer Hall Sensor Interface and the commutation event with the corresponding
|
||||
Interrupt and DMA request if needed (Note that One Timer is used to interface
|
||||
with the Hall sensor Interface and another Timer should be used to use
|
||||
the commutation event).
|
||||
|
||||
(#) Activate the TIM peripheral using one of the start functions:
|
||||
(++) Complementary Output Compare : HAL_TIMEx_OCN_Start(), HAL_TIMEx_OCN_Start_DMA(), HAL_TIMEx_OC_Start_IT()
|
||||
(++) Complementary PWM generation : HAL_TIMEx_PWMN_Start(), HAL_TIMEx_PWMN_Start_DMA(), HAL_TIMEx_PWMN_Start_IT()
|
||||
(++) Complementary One-pulse mode output : HAL_TIMEx_OnePulseN_Start(), HAL_TIMEx_OnePulseN_Start_IT()
|
||||
(++) Hall Sensor output : HAL_TIMEx_HallSensor_Start(), HAL_TIMEx_HallSensor_Start_DMA(), HAL_TIMEx_HallSensor_Start_IT().
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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 TIMEx TIMEx
|
||||
* @brief TIM Extended HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState);
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup TIMEx_Exported_Functions TIM Extended Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group1 Extended Timer Hall Sensor functions
|
||||
* @brief Timer Hall Sensor functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Hall Sensor functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Initialize and configure TIM HAL Sensor.
|
||||
(+) De-initialize TIM HAL Sensor.
|
||||
(+) Start the Hall Sensor Interface.
|
||||
(+) Stop the Hall Sensor Interface.
|
||||
(+) Start the Hall Sensor Interface and enable interrupts.
|
||||
(+) Stop the Hall Sensor Interface and disable interrupts.
|
||||
(+) Start the Hall Sensor Interface and enable DMA transfers.
|
||||
(+) Stop the Hall Sensor Interface and disable DMA transfers.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Initializes the TIM Hall Sensor Interface and initialize the associated handle.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @param sConfig TIM Hall Sensor configuration structure
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Init(TIM_HandleTypeDef *htim, TIM_HallSensor_InitTypeDef *sConfig)
|
||||
{
|
||||
TIM_OC_InitTypeDef OC_Config;
|
||||
|
||||
/* Check the TIM handle allocation */
|
||||
if (htim == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_COUNTER_MODE(htim->Init.CounterMode));
|
||||
assert_param(IS_TIM_CLOCKDIVISION_DIV(htim->Init.ClockDivision));
|
||||
assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
|
||||
assert_param(IS_TIM_IC_POLARITY(sConfig->IC1Polarity));
|
||||
assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
|
||||
assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
|
||||
|
||||
if (htim->State == HAL_TIM_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
htim->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
/* Reset interrupt callbacks to legacy week callbacks */
|
||||
TIM_ResetCallback(htim);
|
||||
|
||||
if (htim->HallSensor_MspInitCallback == NULL)
|
||||
{
|
||||
htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit;
|
||||
}
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC */
|
||||
htim->HallSensor_MspInitCallback(htim);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
|
||||
HAL_TIMEx_HallSensor_MspInit(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/* Set the TIM state */
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Configure the Time base in the Encoder Mode */
|
||||
TIM_Base_SetConfig(htim->Instance, &htim->Init);
|
||||
|
||||
/* Configure the Channel 1 as Input Channel to interface with the three Outputs of the Hall sensor */
|
||||
TIM_TI1_SetConfig(htim->Instance, sConfig->IC1Polarity, TIM_ICSELECTION_TRC, sConfig->IC1Filter);
|
||||
|
||||
/* Reset the IC1PSC Bits */
|
||||
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
|
||||
/* Set the IC1PSC value */
|
||||
htim->Instance->CCMR1 |= sConfig->IC1Prescaler;
|
||||
|
||||
/* Enable the Hall sensor interface (XOR function of the three inputs) */
|
||||
htim->Instance->CR2 |= TIM_CR2_TI1S;
|
||||
|
||||
/* Select the TIM_TS_TI1F_ED signal as Input trigger for the TIM */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= TIM_TS_TI1F_ED;
|
||||
|
||||
/* Use the TIM_TS_TI1F_ED signal to reset the TIM counter each edge detection */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_SMS;
|
||||
htim->Instance->SMCR |= TIM_SLAVEMODE_RESET;
|
||||
|
||||
/* Program channel 2 in PWM 2 mode with the desired Commutation_Delay*/
|
||||
OC_Config.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
OC_Config.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
OC_Config.OCMode = TIM_OCMODE_PWM2;
|
||||
OC_Config.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
OC_Config.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
OC_Config.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
OC_Config.Pulse = sConfig->Commutation_Delay;
|
||||
|
||||
TIM_OC2_SetConfig(htim->Instance, &OC_Config);
|
||||
|
||||
/* Select OC2REF as trigger output on TRGO: write the MMS bits in the TIMx_CR2
|
||||
register to 101 */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_MMS;
|
||||
htim->Instance->CR2 |= TIM_TRGO_OC2REF;
|
||||
|
||||
/* Initialize the TIM state*/
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the TIM Hall Sensor interface
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_DeInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(htim->Instance));
|
||||
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Disable the TIM Peripheral Clock */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
if (htim->HallSensor_MspDeInitCallback == NULL)
|
||||
{
|
||||
htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit;
|
||||
}
|
||||
/* DeInit the low level hardware */
|
||||
htim->HallSensor_MspDeInitCallback(htim);
|
||||
#else
|
||||
/* DeInit the low level hardware: GPIO, CLOCK, NVIC */
|
||||
HAL_TIMEx_HallSensor_MspDeInit(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
|
||||
/* Change TIM state */
|
||||
htim->State = HAL_TIM_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the TIM Hall Sensor MSP.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_HallSensor_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes TIM Hall Sensor MSP.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_HallSensor_MspDeInit(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_HallSensor_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall sensor Interface.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channels 1, 2 and 3
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface in interrupt mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_IT(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Enable the capture compare Interrupts 1 event */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall Sensor Interface in interrupt mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_IT(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
/* Disable the capture compare Interrupts event */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief Starts the TIM Hall Sensor Interface in DMA mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @param pData The destination Buffer address.
|
||||
* @param Length The length of data to be transferred from TIM peripheral to memory.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Start_DMA(TIM_HandleTypeDef *htim, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
if (htim->State == HAL_TIM_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if (htim->State == HAL_TIM_STATE_READY)
|
||||
{
|
||||
if (((uint32_t)pData == 0U) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
/* Enable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
|
||||
|
||||
/* Set the DMA Input Capture 1 Callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMACaptureCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMACaptureHalfCplt;
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel for Capture 1*/
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)&htim->Instance->CCR1, (uint32_t)pData, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the capture compare 1 Interrupt */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Hall Sensor Interface in DMA mode.
|
||||
* @param htim TIM Hall Sensor Interface handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_HallSensor_Stop_DMA(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(htim->Instance));
|
||||
|
||||
/* Disable the Input Capture channel 1
|
||||
(in the Hall Sensor Interface the three possible channels that can be used are TIM_CHANNEL_1, TIM_CHANNEL_2 and TIM_CHANNEL_3) */
|
||||
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
|
||||
|
||||
|
||||
/* Disable the capture compare Interrupts 1 event */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group2 Extended Timer Complementary Output Compare functions
|
||||
* @brief Timer Complementary Output Compare functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary Output Compare functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary Output Compare/PWM.
|
||||
(+) Stop the Complementary Output Compare/PWM.
|
||||
(+) Start the Complementary Output Compare/PWM and enable interrupts.
|
||||
(+) Stop the Complementary Output Compare/PWM and disable interrupts.
|
||||
(+) Start the Complementary Output Compare/PWM and enable DMA transfers.
|
||||
(+) Stop the Complementary Output Compare/PWM and disable DMA transfers.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation in interrupt mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM OC handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Enable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable the TIM Break interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
|
||||
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation in interrupt mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpccer;
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Output Compare interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the TIM Break interrupt (only if no more channel is active) */
|
||||
tmpccer = htim->Instance->CCER;
|
||||
if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
|
||||
{
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
|
||||
}
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief Starts the TIM Output Compare signal generation in DMA mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @param pData The source Buffer address.
|
||||
* @param Length The length of data to be transferred from memory to TIM peripheral
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
if (htim->State == HAL_TIM_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if (htim->State == HAL_TIM_STATE_READY)
|
||||
{
|
||||
if (((uint32_t)pData == 0U) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM Output Compare signal generation in DMA mode
|
||||
* on the complementary output.
|
||||
* @param htim TIM Output Compare handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OCN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Output Compare DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable the Capture compare channel N */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group3 Extended Timer Complementary PWM functions
|
||||
* @brief Timer Complementary PWM functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary PWM functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary PWM.
|
||||
(+) Stop the Complementary PWM.
|
||||
(+) Start the Complementary PWM and enable interrupts.
|
||||
(+) Stop the Complementary PWM and disable interrupts.
|
||||
(+) Start the Complementary PWM and enable DMA transfers.
|
||||
(+) Stop the Complementary PWM and disable DMA transfers.
|
||||
(+) Start the Complementary Input Capture measurement.
|
||||
(+) Stop the Complementary Input Capture.
|
||||
(+) Start the Complementary Input Capture and enable interrupts.
|
||||
(+) Stop the Complementary Input Capture and disable interrupts.
|
||||
(+) Start the Complementary Input Capture and enable DMA transfers.
|
||||
(+) Stop the Complementary Input Capture and disable DMA transfers.
|
||||
(+) Start the Complementary One Pulse generation.
|
||||
(+) Stop the Complementary One Pulse.
|
||||
(+) Start the Complementary One Pulse and enable interrupts.
|
||||
(+) Stop the Complementary One Pulse and disable interrupts.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the PWM signal generation on the complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the PWM signal generation on the complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the PWM signal generation in interrupt mode on the
|
||||
* complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Enable the TIM Capture/Compare 3 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable the TIM Break interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_BREAK);
|
||||
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the PWM signal generation in interrupt mode on the
|
||||
* complementary output.
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 3 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the TIM Break interrupt (only if no more channel is active) */
|
||||
tmpccer = htim->Instance->CCER;
|
||||
if ((tmpccer & (TIM_CCER_CC1NE | TIM_CCER_CC2NE | TIM_CCER_CC3NE)) == (uint32_t)RESET)
|
||||
{
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_BREAK);
|
||||
}
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief Starts the TIM PWM signal generation in DMA mode on the
|
||||
* complementary output
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @param pData The source Buffer address.
|
||||
* @param Length The length of data to be transferred from memory to TIM peripheral
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)
|
||||
{
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
if (htim->State == HAL_TIM_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
else if (htim->State == HAL_TIM_STATE_READY)
|
||||
{
|
||||
if (((uint32_t)pData == 0U) && (Length > 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nothing to do */
|
||||
}
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC1]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC1], (uint32_t)pData, (uint32_t)&htim->Instance->CCR1, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 1 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC1);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC2]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)&htim->Instance->CCR2, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 2 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC2);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Set the DMA compare callbacks */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferCpltCallback = TIM_DMADelayPulseCplt;
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferHalfCpltCallback = TIM_DMADelayPulseHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_CC3]->XferErrorCallback = TIM_DMAError ;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
if (HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC3], (uint32_t)pData, (uint32_t)&htim->Instance->CCR3, Length) != HAL_OK)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Enable the TIM Capture/Compare 3 DMA request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_CC3);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Enable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Enable the Peripheral, except in trigger mode where enable is automatically done with trigger */
|
||||
tmpsmcr = htim->Instance->SMCR & TIM_SMCR_SMS;
|
||||
if (!IS_TIM_SLAVEMODE_TRIGGER_ENABLED(tmpsmcr))
|
||||
{
|
||||
__HAL_TIM_ENABLE(htim);
|
||||
}
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM PWM signal generation in DMA mode on the complementary
|
||||
* output
|
||||
* @param htim TIM handle
|
||||
* @param Channel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_PWMN_Stop_DMA(TIM_HandleTypeDef *htim, uint32_t Channel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, Channel));
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case TIM_CHANNEL_1:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 1 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC1);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC1]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_2:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 2 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC2);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC2]);
|
||||
break;
|
||||
}
|
||||
|
||||
case TIM_CHANNEL_3:
|
||||
{
|
||||
/* Disable the TIM Capture/Compare 3 DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_CC3);
|
||||
(void)HAL_DMA_Abort_IT(htim->hdma[TIM_DMA_ID_CC3]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable the complementary PWM output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, Channel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group4 Extended Timer Complementary One Pulse functions
|
||||
* @brief Timer Complementary One Pulse functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Timer Complementary One Pulse functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Start the Complementary One Pulse generation.
|
||||
(+) Stop the Complementary One Pulse.
|
||||
(+) Start the Complementary One Pulse and enable interrupts.
|
||||
(+) Stop the Complementary One Pulse and disable interrupts.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM One Pulse signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Enable the complementary One Pulse output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM One Pulse signal generation on the complementary
|
||||
* output.
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Disable the complementary One Pulse output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts the TIM One Pulse signal generation in interrupt mode on the
|
||||
* complementary channel.
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel TIM Channel to be enabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Enable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Enable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
|
||||
|
||||
/* Enable the complementary One Pulse output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_ENABLE);
|
||||
|
||||
/* Enable the Main Output */
|
||||
__HAL_TIM_MOE_ENABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the TIM One Pulse signal generation in interrupt mode on the
|
||||
* complementary channel.
|
||||
* @param htim TIM One Pulse handle
|
||||
* @param OutputChannel TIM Channel to be disabled
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_OnePulseN_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CCXN_INSTANCE(htim->Instance, OutputChannel));
|
||||
|
||||
/* Disable the TIM Capture/Compare 1 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
|
||||
|
||||
/* Disable the TIM Capture/Compare 2 interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
|
||||
|
||||
/* Disable the complementary One Pulse output */
|
||||
TIM_CCxNChannelCmd(htim->Instance, OutputChannel, TIM_CCxN_DISABLE);
|
||||
|
||||
/* Disable the Main Output */
|
||||
__HAL_TIM_MOE_DISABLE(htim);
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_TIM_DISABLE(htim);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group5 Extended Peripheral Control functions
|
||||
* @brief Peripheral Control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Configure the commutation event in case of use of the Hall sensor interface.
|
||||
(+) Configure Output channels for OC and PWM mode.
|
||||
|
||||
(+) Configure Complementary channels, break features and dead time.
|
||||
(+) Configure Master synchronization.
|
||||
(+) Configure timer remapping capabilities.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
/* Disable Commutation Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
#if (defined(DMA) || defined(DNA1))
|
||||
/* Disable Commutation DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
|
||||
#endif
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence with interrupt.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_IT(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/* Disable Commutation DMA request */
|
||||
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_COM);
|
||||
#endif
|
||||
|
||||
/* Enable the Commutation Interrupt */
|
||||
__HAL_TIM_ENABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief Configure the TIM commutation event sequence with DMA.
|
||||
* @note This function is mandatory to use the commutation event in order to
|
||||
* update the configuration at each commutation detection on the TRGI input of the Timer,
|
||||
* the typical use of this feature is with the use of another Timer(interface Timer)
|
||||
* configured in Hall sensor interface, this interface Timer will generate the
|
||||
* commutation at its TRGO output (connected to Timer used in this function) each time
|
||||
* the TI1 of the Interface Timer detect a commutation at its input TI1.
|
||||
* @note The user should configure the DMA in his own software, in This function only the COMDE bit is set
|
||||
* @param htim TIM handle
|
||||
* @param InputTrigger the Internal trigger corresponding to the Timer Interfacing with the Hall sensor
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_TS_ITR0: Internal trigger 0 selected
|
||||
* @arg TIM_TS_ITR1: Internal trigger 1 selected
|
||||
* @arg TIM_TS_ITR2: Internal trigger 2 selected
|
||||
* @arg TIM_TS_ITR3: Internal trigger 3 selected
|
||||
* @arg TIM_TS_NONE: No trigger is needed
|
||||
* @param CommutationSource the Commutation Event source
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_COMMUTATION_TRGI: Commutation source is the TRGI of the Interface Timer
|
||||
* @arg TIM_COMMUTATION_SOFTWARE: Commutation source is set by software using the COMG bit
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigCommutEvent_DMA(TIM_HandleTypeDef *htim, uint32_t InputTrigger,
|
||||
uint32_t CommutationSource)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_COMMUTATION_EVENT_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_INTERNAL_TRIGGEREVENT_SELECTION(InputTrigger));
|
||||
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
if ((InputTrigger == TIM_TS_ITR0) || (InputTrigger == TIM_TS_ITR1) ||
|
||||
(InputTrigger == TIM_TS_ITR2) || (InputTrigger == TIM_TS_ITR3))
|
||||
{
|
||||
/* Select the Input trigger */
|
||||
htim->Instance->SMCR &= ~TIM_SMCR_TS;
|
||||
htim->Instance->SMCR |= InputTrigger;
|
||||
}
|
||||
|
||||
/* Select the Capture Compare preload feature */
|
||||
htim->Instance->CR2 |= TIM_CR2_CCPC;
|
||||
/* Select the Commutation event source */
|
||||
htim->Instance->CR2 &= ~TIM_CR2_CCUS;
|
||||
htim->Instance->CR2 |= CommutationSource;
|
||||
|
||||
/* Enable the Commutation DMA Request */
|
||||
/* Set the DMA Commutation Callback */
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferCpltCallback = TIMEx_DMACommutationCplt;
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferHalfCpltCallback = TIMEx_DMACommutationHalfCplt;
|
||||
/* Set the DMA error callback */
|
||||
htim->hdma[TIM_DMA_ID_COMMUTATION]->XferErrorCallback = TIM_DMAError;
|
||||
|
||||
/* Disable Commutation Interrupt */
|
||||
__HAL_TIM_DISABLE_IT(htim, TIM_IT_COM);
|
||||
|
||||
/* Enable the Commutation DMA Request */
|
||||
__HAL_TIM_ENABLE_DMA(htim, TIM_DMA_COM);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @brief Configures the TIM in master mode.
|
||||
* @param htim TIM handle.
|
||||
* @param sMasterConfig pointer to a TIM_MasterConfigTypeDef structure that
|
||||
* contains the selected trigger output (TRGO) and the Master/Slave
|
||||
* mode.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_MasterConfigSynchronization(TIM_HandleTypeDef *htim,
|
||||
TIM_MasterConfigTypeDef *sMasterConfig)
|
||||
{
|
||||
uint32_t tmpcr2;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_MASTER_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_TRGO_SOURCE(sMasterConfig->MasterOutputTrigger));
|
||||
assert_param(IS_TIM_MSM_STATE(sMasterConfig->MasterSlaveMode));
|
||||
|
||||
/* Check input state */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Change the handler state */
|
||||
htim->State = HAL_TIM_STATE_BUSY;
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = htim->Instance->CR2;
|
||||
|
||||
/* Get the TIMx SMCR register value */
|
||||
tmpsmcr = htim->Instance->SMCR;
|
||||
|
||||
/* Reset the MMS Bits */
|
||||
tmpcr2 &= ~TIM_CR2_MMS;
|
||||
/* Select the TRGO source */
|
||||
tmpcr2 |= sMasterConfig->MasterOutputTrigger;
|
||||
|
||||
/* Update TIMx CR2 */
|
||||
htim->Instance->CR2 = tmpcr2;
|
||||
|
||||
if (IS_TIM_SLAVE_INSTANCE(htim->Instance))
|
||||
{
|
||||
/* Reset the MSM Bit */
|
||||
tmpsmcr &= ~TIM_SMCR_MSM;
|
||||
/* Set master mode */
|
||||
tmpsmcr |= sMasterConfig->MasterSlaveMode;
|
||||
|
||||
/* Update TIMx SMCR */
|
||||
htim->Instance->SMCR = tmpsmcr;
|
||||
}
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the Break feature, dead time, Lock level, OSSI/OSSR State
|
||||
* and the AOE(automatic output enable).
|
||||
* @param htim TIM handle
|
||||
* @param sBreakDeadTimeConfig pointer to a TIM_ConfigBreakDeadConfigTypeDef structure that
|
||||
* contains the BDTR Register configuration information for the TIM peripheral.
|
||||
* @note Interrupts can be generated when an active level is detected on the
|
||||
* break input, the break 2 input or the system break input. Break
|
||||
* interrupt can be enabled by calling the @ref __HAL_TIM_ENABLE_IT macro.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_ConfigBreakDeadTime(TIM_HandleTypeDef *htim,
|
||||
TIM_BreakDeadTimeConfigTypeDef *sBreakDeadTimeConfig)
|
||||
{
|
||||
/* Keep this variable initialized to 0 as it is used to configure BDTR register */
|
||||
uint32_t tmpbdtr = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK_INSTANCE(htim->Instance));
|
||||
assert_param(IS_TIM_OSSR_STATE(sBreakDeadTimeConfig->OffStateRunMode));
|
||||
assert_param(IS_TIM_OSSI_STATE(sBreakDeadTimeConfig->OffStateIDLEMode));
|
||||
assert_param(IS_TIM_LOCK_LEVEL(sBreakDeadTimeConfig->LockLevel));
|
||||
assert_param(IS_TIM_DEADTIME(sBreakDeadTimeConfig->DeadTime));
|
||||
assert_param(IS_TIM_BREAK_STATE(sBreakDeadTimeConfig->BreakState));
|
||||
assert_param(IS_TIM_BREAK_POLARITY(sBreakDeadTimeConfig->BreakPolarity));
|
||||
assert_param(IS_TIM_AUTOMATIC_OUTPUT_STATE(sBreakDeadTimeConfig->AutomaticOutput));
|
||||
|
||||
/* Check input state */
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
|
||||
the OSSI State, the dead time value and the Automatic Output Enable Bit */
|
||||
|
||||
/* Set the BDTR bits */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, sBreakDeadTimeConfig->DeadTime);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, sBreakDeadTimeConfig->LockLevel);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, sBreakDeadTimeConfig->OffStateIDLEMode);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, sBreakDeadTimeConfig->OffStateRunMode);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, sBreakDeadTimeConfig->BreakState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, sBreakDeadTimeConfig->BreakPolarity);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, sBreakDeadTimeConfig->AutomaticOutput);
|
||||
|
||||
|
||||
/* Set TIMx_BDTR */
|
||||
htim->Instance->BDTR = tmpbdtr;
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if defined(TIM14)
|
||||
/**
|
||||
* @brief Configures the TIMx Remapping input capabilities.
|
||||
* @param htim TIM handle.
|
||||
* @param Remap specifies the TIM remapping source.
|
||||
* For TIM14, the parameter can have the following values:
|
||||
* @arg TIM_TIM14_GPIO: TIM14 TI1 is connected to GPIO
|
||||
* @arg TIM_TIM14_RTC: TIM14 TI1 is connected to RTC_clock
|
||||
* @arg TIM_TIM14_HSE: TIM14 TI1 is connected to HSE/32
|
||||
* @arg TIM_TIM14_MCO: TIM14 TI1 is connected to MCO
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_TIMEx_RemapConfig(TIM_HandleTypeDef *htim, uint32_t Remap)
|
||||
{
|
||||
__HAL_LOCK(htim);
|
||||
|
||||
/* Check parameters */
|
||||
assert_param(IS_TIM_REMAP(htim->Instance, Remap));
|
||||
|
||||
/* Set the Timer remapping configuration */
|
||||
WRITE_REG(htim->Instance->OR, Remap);
|
||||
|
||||
__HAL_UNLOCK(htim);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group6 Extended Callbacks functions
|
||||
* @brief Extended Callbacks functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Extended Callbacks functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides Extended TIM callback functions:
|
||||
(+) Timer Commutation callback
|
||||
(+) Timer Break callback
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Hall commutation changed callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_CommutCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_CommutCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* @brief Hall commutation changed half complete callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_CommutHalfCpltCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_CommutHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Hall Break detection callback in non-blocking mode
|
||||
* @param htim TIM handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_TIMEx_BreakCallback(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(htim);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_TIMEx_BreakCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup TIMEx_Exported_Functions_Group7 Extended Peripheral State functions
|
||||
* @brief Extended Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Extended Peripheral State functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection permits to get in run-time the status of the peripheral
|
||||
and the data flow.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the TIM Hall Sensor interface handle state.
|
||||
* @param htim TIM Hall Sensor handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_TIM_StateTypeDef HAL_TIMEx_HallSensor_GetState(TIM_HandleTypeDef *htim)
|
||||
{
|
||||
return htim->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup TIMEx_Private_Functions TIMEx Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
/**
|
||||
* @brief TIM DMA Commutation callback.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
void TIMEx_DMACommutationCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->CommutationCallback(htim);
|
||||
#else
|
||||
HAL_TIMEx_CommutCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TIM DMA Commutation half complete callback.
|
||||
* @param hdma pointer to DMA handle.
|
||||
* @retval None
|
||||
*/
|
||||
void TIMEx_DMACommutationHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
TIM_HandleTypeDef *htim = (TIM_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Change the htim state */
|
||||
htim->State = HAL_TIM_STATE_READY;
|
||||
|
||||
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
|
||||
htim->CommutationHalfCpltCallback(htim);
|
||||
#else
|
||||
HAL_TIMEx_CommutHalfCpltCallback(htim);
|
||||
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
/**
|
||||
* @brief Enables or disables the TIM Capture Compare Channel xN.
|
||||
* @param TIMx to select the TIM peripheral
|
||||
* @param Channel specifies the TIM Channel
|
||||
* This parameter can be one of the following values:
|
||||
* @arg TIM_CHANNEL_1: TIM Channel 1
|
||||
* @arg TIM_CHANNEL_2: TIM Channel 2
|
||||
* @arg TIM_CHANNEL_3: TIM Channel 3
|
||||
* @param ChannelNState specifies the TIM Channel CCxNE bit new state.
|
||||
* This parameter can be: TIM_CCxN_ENABLE or TIM_CCxN_Disable.
|
||||
* @retval None
|
||||
*/
|
||||
static void TIM_CCxNChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelNState)
|
||||
{
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = TIM_CCER_CC1NE << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
|
||||
|
||||
/* Reset the CCxNE Bit */
|
||||
TIMx->CCER &= ~tmp;
|
||||
|
||||
/* Set or reset the CCxNE Bit */
|
||||
TIMx->CCER |= (uint32_t)(ChannelNState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
3173
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_uart.c
Normal file
3173
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_uart.c
Normal file
@@ -0,0 +1,3173 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_uart.c
|
||||
* @author MCU Application Team
|
||||
* @brief UART HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Universal Asynchronous Receiver Transmitter Peripheral (UART).
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral Control functions
|
||||
* + Peripheral State and Errors functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The UART HAL driver can be used as follows:
|
||||
|
||||
(#) Declare a UART_HandleTypeDef handle structure (eg. UART_HandleTypeDef huart).
|
||||
(#) Initialize the UART low level resources by implementing the HAL_UART_MspInit() API:
|
||||
(##) Enable the USARTx interface clock.
|
||||
(##) UART pins configuration:
|
||||
(+++) Enable the clock for the UART GPIOs.
|
||||
(+++) Configure these UART pins (TX as alternate function pull-up, RX as alternate function Input).
|
||||
(##) NVIC configuration if you need to use interrupt process (HAL_UART_Transmit_IT()
|
||||
and HAL_UART_Receive_IT() APIs):
|
||||
(+++) Configure the USARTx interrupt priority.
|
||||
(+++) Enable the NVIC USART IRQ handle.
|
||||
(##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
|
||||
and HAL_UART_Receive_DMA() APIs):
|
||||
(+++) Declare a DMA handle structure for the Tx/Rx channel.
|
||||
(+++) Enable the DMAx interface clock.
|
||||
(+++) Configure the declared DMA handle structure with the required
|
||||
Tx/Rx parameters.
|
||||
(+++) Configure the DMA Tx/Rx channel.
|
||||
(+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
|
||||
(+++) Configure the priority and enable the NVIC for the transfer complete
|
||||
interrupt on the DMA Tx/Rx channel.
|
||||
(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
|
||||
(used for last byte sending completion detection in DMA non circular mode)
|
||||
|
||||
(#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
|
||||
flow control and Mode(Receiver/Transmitter) in the huart Init structure.
|
||||
|
||||
(#) For the UART asynchronous mode, initialize the UART registers by calling
|
||||
the HAL_UART_Init() API.
|
||||
|
||||
(#) For the UART Half duplex mode, initialize the UART registers by calling
|
||||
the HAL_HalfDuplex_Init() API.
|
||||
|
||||
(#) For the LIN mode, initialize the UART registers by calling the HAL_LIN_Init() API.
|
||||
|
||||
(#) For the Multi-Processor mode, initialize the UART registers by calling
|
||||
the HAL_MultiProcessor_Init() API.
|
||||
|
||||
[..]
|
||||
(@) The specific UART interrupts (Transmission complete interrupt,
|
||||
RXNE interrupt and Error Interrupts) will be managed using the macros
|
||||
__HAL_UART_ENABLE_IT() and __HAL_UART_DISABLE_IT() inside the transmit
|
||||
and receive process.
|
||||
|
||||
[..]
|
||||
(@) These APIs (HAL_UART_Init() and HAL_HalfDuplex_Init()) configure also the
|
||||
low level Hardware GPIO, CLOCK, CORTEX...etc) by calling the customized
|
||||
HAL_UART_MspInit() API.
|
||||
|
||||
##### Callback registration #####
|
||||
==================================
|
||||
|
||||
[..]
|
||||
The compilation define USE_HAL_UART_REGISTER_CALLBACKS when set to 1
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
|
||||
[..]
|
||||
Use Function @ref HAL_UART_RegisterCallback() to register a user callback.
|
||||
Function @ref HAL_UART_RegisterCallback() allows to register following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
|
||||
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
|
||||
(+) MspInitCallback : UART MspInit.
|
||||
(+) MspDeInitCallback : UART MspDeInit.
|
||||
This function takes as parameters the HAL peripheral handle, the Callback ID
|
||||
and a pointer to the user callback function.
|
||||
|
||||
[..]
|
||||
Use function @ref HAL_UART_UnRegisterCallback() to reset a callback to the default
|
||||
weak (surcharged) function.
|
||||
@ref HAL_UART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
This function allows to reset following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) AbortTransmitCpltCallback : Abort Transmit Complete Callback.
|
||||
(+) AbortReceiveCpltCallback : Abort Receive Complete Callback.
|
||||
(+) MspInitCallback : UART MspInit.
|
||||
(+) MspDeInitCallback : UART MspDeInit.
|
||||
|
||||
[..]
|
||||
By default, after the @ref HAL_UART_Init() and when the state is HAL_UART_STATE_RESET
|
||||
all callbacks are set to the corresponding weak (surcharged) functions:
|
||||
examples @ref HAL_UART_TxCpltCallback(), @ref HAL_UART_RxHalfCpltCallback().
|
||||
Exception done for MspInit and MspDeInit functions that are respectively
|
||||
reset to the legacy weak (surcharged) functions in the @ref HAL_UART_Init()
|
||||
and @ref HAL_UART_DeInit() only when these callbacks are null (not registered beforehand).
|
||||
If not, MspInit or MspDeInit are not null, the @ref HAL_UART_Init() and @ref HAL_UART_DeInit()
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
|
||||
|
||||
[..]
|
||||
Callbacks can be registered/unregistered in HAL_UART_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit that can be registered/unregistered
|
||||
in HAL_UART_STATE_READY or HAL_UART_STATE_RESET state, thus registered (user)
|
||||
MspInit/DeInit callbacks can be used during the Init/DeInit.
|
||||
In that case first register the MspInit/MspDeInit user callbacks
|
||||
using @ref HAL_UART_RegisterCallback() before calling @ref HAL_UART_DeInit()
|
||||
or @ref HAL_UART_Init() function.
|
||||
|
||||
[..]
|
||||
When The compilation define USE_HAL_UART_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available
|
||||
and weak (surcharged) callbacks are used.
|
||||
|
||||
[..]
|
||||
Three operation modes are available within this driver :
|
||||
|
||||
*** Polling mode IO operation ***
|
||||
=================================
|
||||
[..]
|
||||
(+) Send an amount of data in blocking mode using HAL_UART_Transmit()
|
||||
(+) Receive an amount of data in blocking mode using HAL_UART_Receive()
|
||||
|
||||
*** Interrupt mode IO operation ***
|
||||
===================================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode using HAL_UART_Transmit_IT()
|
||||
(+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode using HAL_UART_Receive_IT()
|
||||
(+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_ErrorCallback
|
||||
|
||||
*** DMA mode IO operation ***
|
||||
==============================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode (DMA) using HAL_UART_Transmit_DMA()
|
||||
(+) At transmission end of half transfer HAL_UART_TxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_TxHalfCpltCallback
|
||||
(+) At transmission end of transfer HAL_UART_TxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode (DMA) using HAL_UART_Receive_DMA()
|
||||
(+) At reception end of half transfer HAL_UART_RxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_RxHalfCpltCallback
|
||||
(+) At reception end of transfer HAL_UART_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_UART_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_UART_ErrorCallback
|
||||
(+) Pause the DMA Transfer using HAL_UART_DMAPause()
|
||||
(+) Resume the DMA Transfer using HAL_UART_DMAResume()
|
||||
(+) Stop the DMA Transfer using HAL_UART_DMAStop()
|
||||
|
||||
*** UART HAL driver macros list ***
|
||||
=============================================
|
||||
[..]
|
||||
Below the list of most used macros in UART HAL driver.
|
||||
|
||||
(+) __HAL_UART_ENABLE: Enable the UART peripheral
|
||||
(+) __HAL_UART_DISABLE: Disable the UART peripheral
|
||||
(+) __HAL_UART_GET_FLAG : Check whether the specified UART flag is set or not
|
||||
(+) __HAL_UART_CLEAR_FLAG : Clear the specified UART pending flag
|
||||
(+) __HAL_UART_ENABLE_IT: Enable the specified UART interrupt
|
||||
(+) __HAL_UART_DISABLE_IT: Disable the specified UART interrupt
|
||||
(+) __HAL_UART_GET_IT_SOURCE: Check whether the specified UART interrupt has occurred or not
|
||||
|
||||
[..]
|
||||
(@) You can refer to the UART HAL driver header file for more useful macros
|
||||
|
||||
@endverbatim
|
||||
[..]
|
||||
(@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
the possible UART frame formats are as listed in the following table:
|
||||
+-------------------------------------------------------------+
|
||||
| M bit | PCE bit | UART frame |
|
||||
|---------------------|---------------------------------------|
|
||||
| 0 | 0 | | SB | 8 bit data | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 0 | 1 | | SB | 7 bit data | PB | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 0 | | SB | 9 bit data | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 1 | | SB | 8 bit data | PB | STB | |
|
||||
+-------------------------------------------------------------+
|
||||
******************************************************************************
|
||||
* @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 UART UART
|
||||
* @brief HAL UART module driver
|
||||
* @{
|
||||
*/
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @addtogroup UART_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @addtogroup UART_Private_Functions UART Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
static void UART_EndRxTransfer(UART_HandleTypeDef *huart);
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
static void UART_EndTxTransfer(UART_HandleTypeDef *huart);
|
||||
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMAError(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
#endif /* DMA1 or DMA */
|
||||
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart);
|
||||
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart);
|
||||
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart);
|
||||
static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
|
||||
static void UART_SetConfig(UART_HandleTypeDef *huart);
|
||||
static void UART_AdvFeatureConfig(UART_HandleTypeDef *huart);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
/** @defgroup UART_Exported_Functions UART Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup UART_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to initialize the USARTx or the UARTy
|
||||
in asynchronous mode.
|
||||
(+) For the asynchronous mode only these parameters can be configured:
|
||||
(++) Baud Rate
|
||||
(++) Word Length
|
||||
(++) Stop Bit
|
||||
(++) Parity: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
please refer to Reference manual for possible UART frame formats.
|
||||
(++) Hardware flow control
|
||||
(++) Receiver/transmitter modes
|
||||
(++) Over Sampling Method
|
||||
[..]
|
||||
The HAL_UART_Init(), HAL_HalfDuplex_Init(), HAL_LIN_Init() and HAL_MultiProcessor_Init() APIs
|
||||
follow respectively the UART asynchronous, UART Half duplex, LIN and Multi-Processor configuration
|
||||
procedures (details for the procedures are available in reference manuals
|
||||
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the UART mode according to the specified parameters in
|
||||
* the UART_InitTypeDef and create the associated handle.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the UART handle allocation */
|
||||
if (huart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
if (huart->Init.HwFlowCtl != UART_HWCONTROL_NONE)
|
||||
{
|
||||
/* The hardware flow control is available only for USART1 and USART2 */
|
||||
assert_param(IS_UART_HWFLOW_INSTANCE(huart->Instance));
|
||||
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
}
|
||||
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
|
||||
#if defined(USART_CR3_OVER8)
|
||||
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
|
||||
#endif /* USART_CR3_OVER8 */
|
||||
|
||||
if (huart->gState == HAL_UART_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
huart->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
UART_InitCallbacksToDefault(huart);
|
||||
|
||||
if (huart->MspInitCallback == NULL)
|
||||
{
|
||||
huart->MspInitCallback = HAL_UART_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
huart->MspInitCallback(huart);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK */
|
||||
HAL_UART_MspInit(huart);
|
||||
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
|
||||
}
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_UART_DISABLE(huart);
|
||||
|
||||
/* Set the UART Communication parameters */
|
||||
UART_SetConfig(huart);
|
||||
|
||||
if (huart->AdvancedInit.AdvFeatureInit != UART_ADVFEATURE_NO_INIT)
|
||||
{
|
||||
UART_AdvFeatureConfig(huart);
|
||||
}
|
||||
/* In asynchronous mode, the following bits must be kept cleared:
|
||||
- CLKEN bit in the USART_CR2 register,
|
||||
- HDSEL bit in the USART_CR3 register.*/
|
||||
CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
|
||||
|
||||
/* Enable the peripheral */
|
||||
__HAL_UART_ENABLE(huart);
|
||||
|
||||
/* Initialize the UART state */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the half-duplex mode according to the specified
|
||||
* parameters in the UART_InitTypeDef and create the associated handle.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_HalfDuplex_Init(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the UART handle allocation */
|
||||
if (huart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_HALFDUPLEX_INSTANCE(huart->Instance));
|
||||
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
|
||||
#if defined(USART_CR3_OVER8)
|
||||
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
|
||||
#endif /* USART_CR3_OVER8 */
|
||||
|
||||
if (huart->gState == HAL_UART_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
huart->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
UART_InitCallbacksToDefault(huart);
|
||||
|
||||
if (huart->MspInitCallback == NULL)
|
||||
{
|
||||
huart->MspInitCallback = HAL_UART_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
huart->MspInitCallback(huart);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK */
|
||||
HAL_UART_MspInit(huart);
|
||||
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
|
||||
}
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_UART_DISABLE(huart);
|
||||
|
||||
/* Set the UART Communication parameters */
|
||||
UART_SetConfig(huart);
|
||||
|
||||
/* In half-duplex mode, the following bits must be kept cleared:
|
||||
- CLKEN bit in the USART_CR2 register.*/
|
||||
CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
|
||||
|
||||
/* Enable the Half-Duplex mode by setting the HDSEL bit in the CR3 register */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
|
||||
|
||||
/* Enable the peripheral */
|
||||
__HAL_UART_ENABLE(huart);
|
||||
|
||||
/* Initialize the UART state*/
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the Multi-Processor mode according to the specified
|
||||
* parameters in the UART_InitTypeDef and create the associated handle.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param Address USART address
|
||||
* @param WakeUpMethod specifies the USART wake-up method.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg UART_WAKEUPMETHOD_IDLELINE: Wake-up by an idle line detection
|
||||
* @arg UART_WAKEUPMETHOD_ADDRESSMARK: Wake-up by an address mark
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_MultiProcessor_Init(UART_HandleTypeDef *huart, uint8_t Address, uint32_t WakeUpMethod)
|
||||
{
|
||||
/* Check the UART handle allocation */
|
||||
if (huart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
|
||||
/* Check the Address & wake up method parameters */
|
||||
assert_param(IS_UART_WAKEUPMETHOD(WakeUpMethod));
|
||||
assert_param(IS_UART_ADDRESS(Address));
|
||||
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
|
||||
#if defined(USART_CR3_OVER8)
|
||||
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
|
||||
#endif /* USART_CR3_OVER8 */
|
||||
|
||||
if (huart->gState == HAL_UART_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
huart->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
UART_InitCallbacksToDefault(huart);
|
||||
|
||||
if (huart->MspInitCallback == NULL)
|
||||
{
|
||||
huart->MspInitCallback = HAL_UART_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
huart->MspInitCallback(huart);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK */
|
||||
HAL_UART_MspInit(huart);
|
||||
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
|
||||
}
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_UART_DISABLE(huart);
|
||||
|
||||
/* Set the UART Communication parameters */
|
||||
UART_SetConfig(huart);
|
||||
|
||||
/* In Multi-Processor mode, the following bits must be kept cleared:
|
||||
- LINEN and CLKEN bits in the USART_CR2 register,
|
||||
- SCEN, HDSEL and IREN bits in the USART_CR3 register */
|
||||
CLEAR_BIT(huart->Instance->CR2, USART_CR2_CLKEN);
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_HDSEL);
|
||||
|
||||
/* Set the USART address node */
|
||||
CLEAR_BIT(huart->Instance->CR2, USART_CR2_ADD);
|
||||
SET_BIT(huart->Instance->CR2, Address);
|
||||
|
||||
/* Set the wake up method by setting the WAKE bit in the CR1 register */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_WAKE);
|
||||
SET_BIT(huart->Instance->CR1, WakeUpMethod);
|
||||
|
||||
/* Enable the peripheral */
|
||||
__HAL_UART_ENABLE(huart);
|
||||
|
||||
/* Initialize the UART state */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the UART peripheral.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the UART handle allocation */
|
||||
if (huart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_UART_DISABLE(huart);
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
if (huart->MspDeInitCallback == NULL)
|
||||
{
|
||||
huart->MspDeInitCallback = HAL_UART_MspDeInit;
|
||||
}
|
||||
/* DeInit the low level hardware */
|
||||
huart->MspDeInitCallback(huart);
|
||||
#else
|
||||
/* DeInit the low level hardware */
|
||||
HAL_UART_MspDeInit(huart);
|
||||
#endif /* (USE_HAL_UART_REGISTER_CALLBACKS) */
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_RESET;
|
||||
huart->RxState = HAL_UART_STATE_RESET;
|
||||
|
||||
/* Process Unlock */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP Init.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_MspInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART MSP DeInit.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_MspDeInit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User UART Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param huart uart handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
|
||||
* @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_RegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID, pUART_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
if (huart->gState == HAL_UART_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_UART_TX_HALFCOMPLETE_CB_ID :
|
||||
huart->TxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_TX_COMPLETE_CB_ID :
|
||||
huart->TxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_RX_HALFCOMPLETE_CB_ID :
|
||||
huart->RxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_RX_COMPLETE_CB_ID :
|
||||
huart->RxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_ERROR_CB_ID :
|
||||
huart->ErrorCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_COMPLETE_CB_ID :
|
||||
huart->AbortCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
|
||||
huart->AbortTransmitCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
|
||||
huart->AbortReceiveCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPINIT_CB_ID :
|
||||
huart->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPDEINIT_CB_ID :
|
||||
huart->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (huart->gState == HAL_UART_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_UART_MSPINIT_CB_ID :
|
||||
huart->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPDEINIT_CB_ID :
|
||||
huart->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister an UART Callback
|
||||
* UART callaback is redirected to the weak predefined callback
|
||||
* @param huart uart handle
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_UART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_UART_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_UART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_UART_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_UART_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID Abort Transmit Complete Callback ID
|
||||
* @arg @ref HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID Abort Receive Complete Callback ID
|
||||
* @arg @ref HAL_UART_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_UART_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_UnRegisterCallback(UART_HandleTypeDef *huart, HAL_UART_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
if (HAL_UART_STATE_READY == huart->gState)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_UART_TX_HALFCOMPLETE_CB_ID :
|
||||
huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_TX_COMPLETE_CB_ID :
|
||||
huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_RX_HALFCOMPLETE_CB_ID :
|
||||
huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_RX_COMPLETE_CB_ID :
|
||||
huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_ERROR_CB_ID :
|
||||
huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_COMPLETE_CB_ID :
|
||||
huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_TRANSMIT_COMPLETE_CB_ID :
|
||||
huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_ABORT_RECEIVE_COMPLETE_CB_ID :
|
||||
huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPINIT_CB_ID :
|
||||
huart->MspInitCallback = HAL_UART_MspInit; /* Legacy weak MspInitCallback */
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPDEINIT_CB_ID :
|
||||
huart->MspDeInitCallback = HAL_UART_MspDeInit; /* Legacy weak MspDeInitCallback */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (HAL_UART_STATE_RESET == huart->gState)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_UART_MSPINIT_CB_ID :
|
||||
huart->MspInitCallback = HAL_UART_MspInit;
|
||||
break;
|
||||
|
||||
case HAL_UART_MSPDEINIT_CB_ID :
|
||||
huart->MspDeInitCallback = HAL_UART_MspDeInit;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
huart->ErrorCode |= HAL_UART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup UART_Exported_Functions_Group2 IO operation functions
|
||||
* @brief UART Transmit and Receive functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
This subsection provides a set of functions allowing to manage the UART asynchronous
|
||||
and Half duplex data transfers.
|
||||
|
||||
(#) 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.
|
||||
(+) Non-Blocking mode: The communication is performed using Interrupts
|
||||
or DMA, these API's return the HAL status.
|
||||
The end of the data processing will be indicated through the
|
||||
dedicated UART IRQ when using Interrupt mode or the DMA IRQ when
|
||||
using DMA mode.
|
||||
The HAL_UART_TxCpltCallback(), HAL_UART_RxCpltCallback() user callbacks
|
||||
will be executed respectively at the end of the transmit or receive process
|
||||
The HAL_UART_ErrorCallback()user callback will be executed when a communication error is detected.
|
||||
|
||||
(#) Blocking mode API's are :
|
||||
(+) HAL_UART_Transmit()
|
||||
(+) HAL_UART_Receive()
|
||||
|
||||
(#) Non-Blocking mode API's with Interrupt are :
|
||||
(+) HAL_UART_Transmit_IT()
|
||||
(+) HAL_UART_Receive_IT()
|
||||
(+) HAL_UART_IRQHandler()
|
||||
|
||||
(#) Non-Blocking mode API's with DMA are :
|
||||
(+) HAL_UART_Transmit_DMA()
|
||||
(+) HAL_UART_Receive_DMA()
|
||||
(+) HAL_UART_DMAPause()
|
||||
(+) HAL_UART_DMAResume()
|
||||
(+) HAL_UART_DMAStop()
|
||||
|
||||
(#) A set of Transfer Complete Callbacks are provided in Non_Blocking mode:
|
||||
(+) HAL_UART_TxHalfCpltCallback()
|
||||
(+) HAL_UART_TxCpltCallback()
|
||||
(+) HAL_UART_RxHalfCpltCallback()
|
||||
(+) HAL_UART_RxCpltCallback()
|
||||
(+) HAL_UART_ErrorCallback()
|
||||
|
||||
(#) Non-Blocking mode transfers could be aborted using Abort API's :
|
||||
(+) HAL_UART_Abort()
|
||||
(+) HAL_UART_AbortTransmit()
|
||||
(+) HAL_UART_AbortReceive()
|
||||
(+) HAL_UART_Abort_IT()
|
||||
(+) HAL_UART_AbortTransmit_IT()
|
||||
(+) HAL_UART_AbortReceive_IT()
|
||||
|
||||
(#) For Abort services based on interrupts (HAL_UART_Abortxxx_IT), a set of Abort Complete Callbacks are provided:
|
||||
(+) HAL_UART_AbortCpltCallback()
|
||||
(+) HAL_UART_AbortTransmitCpltCallback()
|
||||
(+) HAL_UART_AbortReceiveCpltCallback()
|
||||
|
||||
(#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
|
||||
Errors are handled as follows :
|
||||
(+) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
|
||||
to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
|
||||
Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
|
||||
and HAL_UART_ErrorCallback() user callback is executed. Transfer is kept ongoing on UART side.
|
||||
If user wants to abort it, Abort services should be called by user.
|
||||
(+) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
|
||||
This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
|
||||
Error code is set to allow user to identify error type, and HAL_UART_ErrorCallback() user callback is executed.
|
||||
|
||||
-@- In the Half duplex communication, it is forbidden to run the transmit
|
||||
and receive process in parallel, the UART state HAL_UART_STATE_BUSY_TX_RX can't be useful.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sends an amount of data in blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pData.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent
|
||||
* @param Timeout Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint8_t *pdata8bits;
|
||||
uint16_t *pdata16bits;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (huart->gState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
|
||||
should be aligned on a u16 frontier, as data to be filled into DR will be
|
||||
handled through a u16 cast. */
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
if ((((uint32_t)pData) & 1U) != 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_BUSY_TX;
|
||||
|
||||
/* Init tickstart for timeout managment */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
huart->TxXferSize = Size;
|
||||
huart->TxXferCount = Size;
|
||||
|
||||
/* In case of 9bits/No Parity transfer, pData needs to be handled as a uint16_t pointer */
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
pdata8bits = NULL;
|
||||
pdata16bits = (uint16_t *) pData;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata8bits = pData;
|
||||
pdata16bits = NULL;
|
||||
}
|
||||
|
||||
|
||||
while (huart->TxXferCount > 0U)
|
||||
{
|
||||
|
||||
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
if (pdata8bits == NULL)
|
||||
{
|
||||
huart->Instance->DR = (uint16_t)(*pdata16bits & 0x01FFU);
|
||||
pdata16bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
huart->Instance->DR = (uint8_t)(*pdata8bits & 0xFFU);
|
||||
pdata8bits++;
|
||||
}
|
||||
|
||||
huart->TxXferCount--;
|
||||
}
|
||||
|
||||
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/* At end of Tx process, restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pData.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @param Timeout Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint8_t *pdata8bits;
|
||||
uint16_t *pdata16bits;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (huart->RxState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
|
||||
should be aligned on a u16 frontier, as data to be received from RDR will be
|
||||
handled through a u16 cast. */
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
if ((((uint32_t)pData) & 1U) != 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->RxState = HAL_UART_STATE_BUSY_RX;
|
||||
|
||||
/* Init tickstart for timeout managment */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
huart->RxXferSize = Size;
|
||||
huart->RxXferCount = Size;
|
||||
|
||||
/* In case of 9bits/No Parity transfer, pRxData needs to be handled as a uint16_t pointer */
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
pdata8bits = NULL;
|
||||
pdata16bits = (uint16_t *) pData;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdata8bits = pData;
|
||||
pdata16bits = NULL;
|
||||
}
|
||||
/* as long as data have to be received */
|
||||
while (huart->RxXferCount > 0U)
|
||||
{
|
||||
if (UART_WaitOnFlagUntilTimeout(huart, UART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
if (pdata8bits == NULL)
|
||||
{
|
||||
*pdata16bits = (uint16_t)(huart->Instance->DR & 0x1FF);
|
||||
pdata16bits++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pdata8bits = (uint8_t)(huart->Instance->DR & (uint8_t)0xFF);
|
||||
pdata8bits++;
|
||||
}
|
||||
huart->RxXferCount--;
|
||||
}
|
||||
/* At end of Rx process, restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sends an amount of data in non blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pData.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (huart->gState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->pTxBuffPtr = pData;
|
||||
huart->TxXferSize = Size;
|
||||
huart->TxXferCount = Size;
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_BUSY_TX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
/* Enable the UART Transmit data register empty Interrupt */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in non blocking mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pData.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (huart->RxState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->pRxBuffPtr = pData;
|
||||
huart->RxXferSize = Size;
|
||||
huart->RxXferCount = Size;
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->RxState = HAL_UART_STATE_BUSY_RX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
/* Enable the UART Parity Error Interrupt */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_PE);
|
||||
|
||||
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_ERR);
|
||||
|
||||
/* Enable the UART Data Register not empty Interrupt */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_RXNE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief Sends an amount of data in DMA mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pData.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
/* Check that a Tx process is not already ongoing */
|
||||
if (huart->gState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->pTxBuffPtr = pData;
|
||||
huart->TxXferSize = Size;
|
||||
huart->TxXferCount = Size;
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->gState = HAL_UART_STATE_BUSY_TX;
|
||||
|
||||
/* Set the UART DMA transfer complete callback */
|
||||
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
|
||||
|
||||
/* Set the UART DMA Half transfer complete callback */
|
||||
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
huart->hdmatx->XferErrorCallback = UART_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the UART transmit DMA channel */
|
||||
tmp = (uint32_t *)&pData;
|
||||
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
|
||||
|
||||
/* Clear the TC flag in the SR register by writing 0 to it */
|
||||
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
/* Enable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the UART CR3 register */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in DMA mode.
|
||||
* @note When UART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pData.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param pData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @note When the UART parity is enabled (PCE = 1) the received data contains the parity bit.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
|
||||
{
|
||||
|
||||
/* Check that a Rx process is not already ongoing */
|
||||
if (huart->RxState == HAL_UART_STATE_READY)
|
||||
{
|
||||
if ((pData == NULL) || (Size == 0U))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* In case of 9bits/No Parity transfer, pData buffer provided as input parameter
|
||||
should be aligned on a u16 frontier, as data copy from RDR will be
|
||||
handled by DMA from a u16 frontier. */
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
if ((((uint32_t)pData) & 1U) != 0U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->pRxBuffPtr = pData;
|
||||
huart->RxXferSize = Size;
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
huart->RxState = HAL_UART_STATE_BUSY_RX;
|
||||
|
||||
/* Set the UART DMA transfer complete callback */
|
||||
huart->hdmarx->XferCpltCallback = UART_DMAReceiveCplt;
|
||||
|
||||
/* Set the UART DMA Half transfer complete callback */
|
||||
huart->hdmarx->XferHalfCpltCallback = UART_DMARxHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
huart->hdmarx->XferErrorCallback = UART_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the DMA channel */
|
||||
HAL_DMA_Start_IT(huart->hdmarx, (uint32_t)&huart->Instance->DR,(uint32_t)huart->pRxBuffPtr, Size);
|
||||
|
||||
/* Clear the Overrun flag just before enabling the DMA Rx request: can be mandatory for the second transfer */
|
||||
__HAL_UART_CLEAR_OREFLAG(huart);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
/* Enable the UART Parity Error Interrupt */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
|
||||
in the UART CR3 register */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pauses the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
/* Disable the UART DMA Tx request */
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the UART DMA Rx request */
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resumes the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_DMAResume(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
if (huart->gState == HAL_UART_STATE_BUSY_TX)
|
||||
{
|
||||
/* Enable the UART DMA Tx request */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
|
||||
{
|
||||
/* Clear the Overrun flag before resuming the Rx transfer*/
|
||||
__HAL_UART_CLEAR_OREFLAG(huart);
|
||||
|
||||
/* Reenable PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_PEIE);
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the UART DMA Rx request */
|
||||
SET_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_DMAStop(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
/* The Lock is not implemented on this API to allow the user application
|
||||
to call the HAL UART API under callbacks HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback():
|
||||
when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
|
||||
and the correspond call back is executed HAL_UART_TxCpltCallback() / HAL_UART_RxCpltCallback()
|
||||
*/
|
||||
|
||||
/* Stop UART DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the UART DMA Tx channel */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(huart->hdmatx);
|
||||
}
|
||||
UART_EndTxTransfer(huart);
|
||||
}
|
||||
|
||||
/* Stop UART DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(huart->hdmarx);
|
||||
}
|
||||
UART_EndRxTransfer(huart);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfers (blocking mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Tx and Rx)
|
||||
* - 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 Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_Abort(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the UART DMA Tx channel: use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
|
||||
{
|
||||
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
|
||||
{
|
||||
/* Set error code to DMA */
|
||||
huart->ErrorCode = HAL_UART_ERROR_DMA;
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the UART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel: use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
|
||||
{
|
||||
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
|
||||
{
|
||||
/* Set error code to DMA */
|
||||
huart->ErrorCode = HAL_UART_ERROR_DMA;
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
huart->TxXferCount = 0x00U;
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
|
||||
/* Restore huart->RxState and huart->gState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Transmit transfer (blocking mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Tx)
|
||||
* - 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_UART_AbortTransmit(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
if (HAL_DMA_Abort(huart->hdmatx) != HAL_OK)
|
||||
{
|
||||
if (HAL_DMA_GetError(huart->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
|
||||
{
|
||||
/* Set error code to DMA */
|
||||
huart->ErrorCode = HAL_UART_ERROR_DMA;
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* Reset Tx transfer counter */
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Receive transfer (blocking mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Rx)
|
||||
* - 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_UART_AbortReceive(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
if (HAL_DMA_Abort(huart->hdmarx) != HAL_OK)
|
||||
{
|
||||
if (HAL_DMA_GetError(huart->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
|
||||
{
|
||||
/* Set error code to DMA */
|
||||
huart->ErrorCode = HAL_UART_ERROR_DMA;
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* Reset Rx transfer counter */
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfers (Interrupt mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Tx and Rx)
|
||||
* - 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_UART_Abort_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t AbortCplt = 0x01U;
|
||||
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* If DMA Tx and/or DMA Rx Handles are associated to UART Handle, DMA Abort complete callbacks should be initialised
|
||||
before any call to DMA Abort functions */
|
||||
/* DMA Tx Handle is valid */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if UART DMA Tx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
huart->hdmatx->XferAbortCallback = UART_DMATxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
/* DMA Rx Handle is valid */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if UART DMA Rx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
huart->hdmarx->XferAbortCallback = UART_DMARxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the UART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
/* Disable DMA Tx at UART level */
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the UART DMA Tx channel : use non blocking DMA Abort API (callback) */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
/* UART Tx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA TX */
|
||||
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
|
||||
{
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the UART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel : use non blocking DMA Abort API (callback) */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* UART Rx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
|
||||
{
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
AbortCplt = 0x01U;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* if no DMA abort complete callback execution is required => call user Abort Complete callback */
|
||||
if (AbortCplt == 0x01U)
|
||||
{
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
huart->TxXferCount = 0x00U;
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
|
||||
/* Restore huart->gState and huart->RxState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
huart->AbortCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_UART_AbortCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Transmit transfer (Interrupt mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing Tx transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Tx)
|
||||
* - 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_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the UART DMA Tx channel : use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback :
|
||||
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
huart->hdmatx->XferAbortCallback = UART_DMATxOnlyAbortCallback;
|
||||
|
||||
/* Abort DMA TX */
|
||||
if (HAL_DMA_Abort_IT(huart->hdmatx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly huart->hdmatx->XferAbortCallback function in case of error */
|
||||
huart->hdmatx->XferAbortCallback(huart->hdmatx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Tx transfer counter */
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
huart->AbortTransmitCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_UART_AbortTransmitCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* DMA1 or DMA */
|
||||
/* Reset Tx transfer counter */
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
huart->AbortTransmitCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_UART_AbortTransmitCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing Receive transfer (Interrupt mode).
|
||||
* @param huart UART handle.
|
||||
* @note This procedure could be used for aborting any ongoing Rx transfer started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable UART Interrupts (Rx)
|
||||
* - 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_UART_AbortReceive_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel : use blocking DMA Abort API (no callback) */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback :
|
||||
will lead to call HAL_UART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
huart->hdmarx->XferAbortCallback = UART_DMARxOnlyAbortCallback;
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly huart->hdmarx->XferAbortCallback function in case of error */
|
||||
huart->hdmarx->XferAbortCallback(huart->hdmarx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reset Rx transfer counter */
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
huart->AbortReceiveCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_UART_AbortReceiveCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* DMA1 or DMA */
|
||||
/* Reset Rx transfer counter */
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
huart->AbortReceiveCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_UART_AbortReceiveCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles UART interrupt request.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t isrflags = READ_REG(huart->Instance->SR);
|
||||
uint32_t cr1its = READ_REG(huart->Instance->CR1);
|
||||
uint32_t cr3its = READ_REG(huart->Instance->CR3);
|
||||
uint32_t errorflags = 0x00U;
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
uint32_t dmarequest = 0x00U;
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* If no error occurs */
|
||||
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
|
||||
if (errorflags == RESET)
|
||||
{
|
||||
/* UART in mode Receiver -------------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
UART_Receive_IT(huart);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If some errors occur */
|
||||
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
|
||||
{
|
||||
/* UART parity error interrupt occurred ----------------------------------*/
|
||||
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
|
||||
{
|
||||
huart->ErrorCode |= HAL_UART_ERROR_PE;
|
||||
}
|
||||
|
||||
/* UART noise error interrupt occurred -----------------------------------*/
|
||||
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
huart->ErrorCode |= HAL_UART_ERROR_NE;
|
||||
}
|
||||
|
||||
/* UART frame error interrupt occurred -----------------------------------*/
|
||||
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
huart->ErrorCode |= HAL_UART_ERROR_FE;
|
||||
}
|
||||
|
||||
/* UART Over-Run interrupt occurred --------------------------------------*/
|
||||
if (((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
huart->ErrorCode |= HAL_UART_ERROR_ORE;
|
||||
}
|
||||
|
||||
/* Call UART Error Call back function if need be --------------------------*/
|
||||
if (huart->ErrorCode != HAL_UART_ERROR_NONE)
|
||||
{
|
||||
/* UART in mode Receiver -----------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
UART_Receive_IT(huart);
|
||||
}
|
||||
|
||||
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
|
||||
consider error as blocking */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || dmarequest)
|
||||
#else
|
||||
if ((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET)
|
||||
#endif /* DMA1 or DMA */
|
||||
{
|
||||
/* Blocking error : transfer is aborted
|
||||
Set the UART state ready to be able to start again the process,
|
||||
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
|
||||
UART_EndRxTransfer(huart);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the UART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the UART DMA Rx channel */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the UART DMA Abort callback :
|
||||
will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */
|
||||
huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError;
|
||||
if (HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly XferAbortCallback function in case of error */
|
||||
huart->hdmarx->XferAbortCallback(huart->hdmarx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call user error callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered error callback*/
|
||||
huart->ErrorCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak error callback*/
|
||||
HAL_UART_ErrorCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* DMA1 or DMA */
|
||||
/* Call user error callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered error callback*/
|
||||
huart->ErrorCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak error callback*/
|
||||
HAL_UART_ErrorCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Non Blocking error : transfer could go on.
|
||||
Error is notified to user through user error callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered error callback*/
|
||||
huart->ErrorCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak error callback*/
|
||||
HAL_UART_ErrorCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
} /* End if some error occurs */
|
||||
|
||||
/* UART in mode Transmitter ------------------------------------------------*/
|
||||
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
|
||||
{
|
||||
UART_Transmit_IT(huart);
|
||||
return;
|
||||
}
|
||||
|
||||
/* UART in mode Transmitter end --------------------------------------------*/
|
||||
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
|
||||
{
|
||||
UART_EndTransmit_IT(huart);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Transfer completed callbacks.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_TxCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Half Transfer completed callbacks.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_TxHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Transfer completed callbacks.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_RxCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Half Transfer completed callbacks.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_RxHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART error callbacks.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_ErrorCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART Abort Complete callback.
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_AbortCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART Abort Complete callback.
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_AbortTransmitCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_AbortTransmitCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART Abort Receive Complete callback.
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_UART_AbortReceiveCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(huart);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_UART_AbortReceiveCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup UART_Exported_Functions_Group3 Peripheral Control functions
|
||||
* @brief UART control functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the UART:
|
||||
(+) HAL_UART_SendBreak() API can be helpful to transmit the break character.
|
||||
(+) HAL_MultiProcessor_EnterMuteMode() API can be helpful to enter the UART in mute mode.
|
||||
(+) HAL_MultiProcessor_ExitMuteMode() API can be helpful to exit the UART mute mode by software.
|
||||
(+) HAL_HalfDuplex_EnableTransmitter() API to enable the UART transmitter and disables the UART receiver in Half Duplex mode
|
||||
(+) HAL_HalfDuplex_EnableReceiver() API to enable the UART receiver and disables the UART transmitter in Half Duplex mode
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Transmits break characters.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_UART_SendBreak(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Send break characters */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_SBK);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters the UART in mute mode.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_MultiProcessor_EnterMuteMode(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Enable the USART mute mode by setting the RWU bit in the CR1 register */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_RWU);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits the UART mute mode: wake up software.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_MultiProcessor_ExitMuteMode(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(huart->Instance));
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/* Disable the USART mute mode by clearing the RWU bit in the CR1 register */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_RWU);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the UART transmitter and disables the UART receiver.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_HalfDuplex_EnableTransmitter(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t tmpreg = 0x00U;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/*-------------------------- USART CR1 Configuration -----------------------*/
|
||||
tmpreg = huart->Instance->CR1;
|
||||
|
||||
/* Clear TE and RE bits */
|
||||
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
|
||||
|
||||
/* Enable the USART's transmit interface by setting the TE bit in the USART CR1 register */
|
||||
tmpreg |= (uint32_t)USART_CR1_TE;
|
||||
|
||||
/* Write to USART CR1 */
|
||||
WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the UART receiver and disables the UART transmitter.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_HalfDuplex_EnableReceiver(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t tmpreg = 0x00U;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(huart);
|
||||
|
||||
huart->gState = HAL_UART_STATE_BUSY;
|
||||
|
||||
/*-------------------------- USART CR1 Configuration -----------------------*/
|
||||
tmpreg = huart->Instance->CR1;
|
||||
|
||||
/* Clear TE and RE bits */
|
||||
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_TE | USART_CR1_RE));
|
||||
|
||||
/* Enable the USART's receive interface by setting the RE bit in the USART CR1 register */
|
||||
tmpreg |= (uint32_t)USART_CR1_RE;
|
||||
|
||||
/* Write to USART CR1 */
|
||||
WRITE_REG(huart->Instance->CR1, (uint32_t)tmpreg);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup UART_Exported_Functions_Group4 Peripheral State and Errors functions
|
||||
* @brief UART State and Errors functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral State and Errors functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to return the State of
|
||||
UART communication process, return Peripheral Errors occurred during communication
|
||||
process
|
||||
(+) HAL_UART_GetState() API can be helpful to check in run-time the state of the UART peripheral.
|
||||
(+) HAL_UART_GetError() check in run-time errors that could be occurred during communication.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Returns the UART state.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_UART_StateTypeDef HAL_UART_GetState(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t temp1 = 0x00U, temp2 = 0x00U;
|
||||
temp1 = huart->gState;
|
||||
temp2 = huart->RxState;
|
||||
|
||||
return (HAL_UART_StateTypeDef)(temp1 | temp2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the UART error code
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART.
|
||||
* @retval UART Error Code
|
||||
*/
|
||||
uint32_t HAL_UART_GetError(UART_HandleTypeDef *huart)
|
||||
{
|
||||
return huart->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup UART_Private_Functions UART Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the callbacks to their default values.
|
||||
* @param huart UART handle.
|
||||
* @retval none
|
||||
*/
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
void UART_InitCallbacksToDefault(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Init the UART Callback settings */
|
||||
huart->TxHalfCpltCallback = HAL_UART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
huart->TxCpltCallback = HAL_UART_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
huart->RxHalfCpltCallback = HAL_UART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
huart->RxCpltCallback = HAL_UART_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
huart->ErrorCallback = HAL_UART_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
huart->AbortCpltCallback = HAL_UART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
huart->AbortTransmitCpltCallback = HAL_UART_AbortTransmitCpltCallback; /* Legacy weak AbortTransmitCpltCallback */
|
||||
huart->AbortReceiveCpltCallback = HAL_UART_AbortReceiveCpltCallback; /* Legacy weak AbortReceiveCpltCallback */
|
||||
|
||||
}
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief DMA UART transmit process complete callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
/* DMA Normal mode*/
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
/* Disable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the UART CR3 register */
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Enable the UART Transmit Complete Interrupt */
|
||||
SET_BIT(huart->Instance->CR1, USART_CR1_TCIE);
|
||||
|
||||
}
|
||||
/* DMA Circular mode */
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Tx complete callback*/
|
||||
huart->TxCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Tx complete callback*/
|
||||
HAL_UART_TxCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART transmit process half complete callback
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Tx complete callback*/
|
||||
huart->TxHalfCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Tx complete callback*/
|
||||
HAL_UART_TxHalfCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART receive process complete callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
/* DMA Normal mode*/
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
huart->RxXferCount = 0U;
|
||||
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, USART_CR1_PEIE);
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the DMA transfer for the receiver request by setting the DMAR bit
|
||||
in the UART CR3 register */
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* At end of Rx process, restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
}
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Rx complete callback*/
|
||||
huart->RxCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Rx complete callback*/
|
||||
HAL_UART_RxCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART receive process half complete callback
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Rx Half complete callback*/
|
||||
huart->RxHalfCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Rx Half complete callback*/
|
||||
HAL_UART_RxHalfCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART communication error callback.
|
||||
* @param hdma Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMAError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
/* Stop UART DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((huart->gState == HAL_UART_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
huart->TxXferCount = 0x00U;
|
||||
UART_EndTxTransfer(huart);
|
||||
}
|
||||
|
||||
/* Stop UART DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((huart->RxState == HAL_UART_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
huart->RxXferCount = 0x00U;
|
||||
UART_EndRxTransfer(huart);
|
||||
}
|
||||
|
||||
huart->ErrorCode |= HAL_UART_ERROR_DMA;
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered error callback*/
|
||||
huart->ErrorCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak error callback*/
|
||||
HAL_UART_ErrorCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief This function handles UART Communication Timeout.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @param Flag specifies the UART flag to check.
|
||||
* @param Status The new Flag status (SET or RESET).
|
||||
* @param Tickstart Tick start value
|
||||
* @param Timeout Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef UART_WaitOnFlagUntilTimeout(UART_HandleTypeDef *huart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
|
||||
{
|
||||
/* Wait until flag is set */
|
||||
while ((__HAL_UART_GET_FLAG(huart, Flag) ? SET : RESET) == Status)
|
||||
{
|
||||
/* Check for the Timeout */
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
|
||||
{
|
||||
/* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(huart);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief End ongoing Tx transfer on UART peripheral (following error detection or Transmit completion).
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_EndTxTransfer(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
/* At end of Tx process, restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief End ongoing Rx transfer on UART peripheral (following error detection or Reception completion).
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_EndRxTransfer(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* At end of Rx process, restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief DMA UART 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 Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
huart->RxXferCount = 0x00U;
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered error callback*/
|
||||
huart->ErrorCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak error callback*/
|
||||
HAL_UART_ErrorCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART 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 Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
huart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (huart->hdmarx != NULL)
|
||||
{
|
||||
if (huart->hdmarx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
huart->TxXferCount = 0x00U;
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
|
||||
/* Restore huart->gState and huart->RxState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
huart->AbortCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_UART_AbortCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART 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 Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA module.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
huart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (huart->hdmatx != NULL)
|
||||
{
|
||||
if (huart->hdmatx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
huart->TxXferCount = 0x00U;
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset ErrorCode */
|
||||
huart->ErrorCode = HAL_UART_ERROR_NONE;
|
||||
|
||||
/* Restore huart->gState and huart->RxState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort complete callback */
|
||||
huart->AbortCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort complete callback */
|
||||
HAL_UART_AbortCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART Tx communication abort callback, when initiated by user by a call to
|
||||
* HAL_UART_AbortTransmit_IT API (Abort only Tx transfer)
|
||||
* (This callback is executed at end of DMA Tx Abort procedure following user abort request,
|
||||
* and leads to user Tx Abort Complete callback execution).
|
||||
* @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 UART_DMATxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
huart->TxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Transmit Complete Callback */
|
||||
huart->AbortTransmitCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Transmit Complete Callback */
|
||||
HAL_UART_AbortTransmitCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA UART Rx communication abort callback, when initiated by user by a call to
|
||||
* HAL_UART_AbortReceive_IT API (Abort only Rx transfer)
|
||||
* (This callback is executed at end of DMA Rx Abort procedure following user abort request,
|
||||
* and leads to user Rx Abort Complete callback execution).
|
||||
* @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 UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
UART_HandleTypeDef *huart = (UART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
huart->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Receive Complete Callback */
|
||||
huart->AbortReceiveCpltCallback(huart);
|
||||
#else
|
||||
/* Call legacy weak Abort Receive Complete Callback */
|
||||
HAL_UART_AbortReceiveCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief Sends an amount of data in non blocking mode.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint16_t *tmp16bit;
|
||||
uint8_t *tmp8bit;
|
||||
/* Check that a Tx process is ongoing */
|
||||
if (huart->gState == HAL_UART_STATE_BUSY_TX)
|
||||
{
|
||||
if ((huart->Init.WordLength == UART_WORDLENGTH_9B)&&(huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
tmp16bit=(uint16_t *) huart->pTxBuffPtr;
|
||||
huart->Instance->DR = (uint16_t)(*tmp16bit & (uint16_t)0x01FF);
|
||||
huart->pTxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
tmp8bit=(uint8_t *) huart->pTxBuffPtr;
|
||||
huart->Instance->DR = (uint8_t)(*tmp8bit & (uint8_t)0x00FF);
|
||||
huart->pTxBuffPtr++;
|
||||
}
|
||||
|
||||
if (--huart->TxXferCount == 0U)
|
||||
{
|
||||
/* Disable the UART Transmit Complete Interrupt */
|
||||
__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
|
||||
|
||||
/* Enable the UART Transmit Complete Interrupt */
|
||||
__HAL_UART_ENABLE_IT(huart, UART_IT_TC);
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wraps up transmission in non blocking mode.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Disable the UART Transmit Complete Interrupt */
|
||||
__HAL_UART_DISABLE_IT(huart, UART_IT_TC);
|
||||
|
||||
/* Tx process is ended, restore huart->gState to Ready */
|
||||
huart->gState = HAL_UART_STATE_READY;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Tx complete callback*/
|
||||
huart->TxCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Tx complete callback*/
|
||||
HAL_UART_TxCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Receives an amount of data in non blocking mode
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint16_t *tmp16bit;
|
||||
/* Check that a Rx process is ongoing */
|
||||
if (huart->RxState == HAL_UART_STATE_BUSY_RX)
|
||||
{
|
||||
/* Set the Rx ISR function pointer according to the data word length */
|
||||
if((huart->Init.WordLength == UART_WORDLENGTH_9B)&& (huart->Init.Parity == UART_PARITY_NONE))
|
||||
{
|
||||
tmp16bit = (uint16_t *) huart->pRxBuffPtr;
|
||||
*tmp16bit = (uint16_t)(huart->Instance->DR & (uint16_t)0x01FF);
|
||||
huart->pRxBuffPtr += 2U;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
|
||||
if (--huart->RxXferCount == 0U)
|
||||
{
|
||||
/* Disable the UART Data Register not empty Interrupt */
|
||||
__HAL_UART_DISABLE_IT(huart, UART_IT_RXNE);
|
||||
|
||||
/* Disable the UART Parity Error Interrupt */
|
||||
__HAL_UART_DISABLE_IT(huart, UART_IT_PE);
|
||||
|
||||
/* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
__HAL_UART_DISABLE_IT(huart, UART_IT_ERR);
|
||||
|
||||
/* Rx process is completed, restore huart->RxState to Ready */
|
||||
huart->RxState = HAL_UART_STATE_READY;
|
||||
|
||||
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1)
|
||||
/*Call registered Rx complete callback*/
|
||||
huart->RxCpltCallback(huart);
|
||||
#else
|
||||
/*Call legacy weak Rx complete callback*/
|
||||
HAL_UART_RxCpltCallback(huart);
|
||||
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the UART peripheral.
|
||||
* @param huart Pointer to a UART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified UART module.
|
||||
* @retval None
|
||||
*/
|
||||
static void UART_SetConfig(UART_HandleTypeDef *huart)
|
||||
{
|
||||
uint32_t tmpreg;
|
||||
uint32_t pclk;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
|
||||
assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
|
||||
assert_param(IS_UART_PARITY(huart->Init.Parity));
|
||||
assert_param(IS_UART_MODE(huart->Init.Mode));
|
||||
|
||||
/*-------------------------- USART CR2 Configuration -----------------------*/
|
||||
/* Configure the UART Stop Bits: Set STOP[13:12] bits
|
||||
according to huart->Init.StopBits value */
|
||||
MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
|
||||
|
||||
/*-------------------------- USART CR1 Configuration -----------------------*/
|
||||
/* Configure the UART Word Length, Parity and mode:
|
||||
Set the M bits according to huart->Init.WordLength value
|
||||
Set PCE and PS bits according to huart->Init.Parity value
|
||||
Set TE and RE bits according to huart->Init.Mode value
|
||||
Set OVER8 bit according to huart->Init.OverSampling value */
|
||||
|
||||
#if defined(USART_CR3_OVER8)
|
||||
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
|
||||
MODIFY_REG(huart->Instance->CR1,
|
||||
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
|
||||
tmpreg);
|
||||
|
||||
tmpreg = (uint32_t) huart->Init.OverSampling;
|
||||
MODIFY_REG(huart->Instance->CR3,
|
||||
(uint32_t)(USART_CR3_OVER8),
|
||||
tmpreg);
|
||||
#else
|
||||
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode;
|
||||
MODIFY_REG(huart->Instance->CR1,
|
||||
(uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE),
|
||||
tmpreg);
|
||||
#endif /* USART_CR3_OVER8 */
|
||||
|
||||
/*-------------------------- USART CR3 Configuration -----------------------*/
|
||||
/* Configure the UART HFC: Set CTSE and RTSE bits according to huart->Init.HwFlowCtl value */
|
||||
MODIFY_REG(huart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE), huart->Init.HwFlowCtl);
|
||||
|
||||
#if defined(USART_CR3_OVER8)
|
||||
/* Check the Over Sampling */
|
||||
if(huart->Init.OverSampling == UART_OVERSAMPLING_8)
|
||||
{
|
||||
/*-------------------------- USART BRR Configuration ---------------------*/
|
||||
pclk = HAL_RCC_GetPCLK1Freq();
|
||||
huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*-------------------------- USART BRR Configuration ---------------------*/
|
||||
pclk = HAL_RCC_GetPCLK1Freq();
|
||||
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
|
||||
}
|
||||
#else
|
||||
/*-------------------------- USART BRR Configuration ---------------------*/
|
||||
|
||||
pclk = HAL_RCC_GetPCLK1Freq();
|
||||
huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
|
||||
|
||||
#endif /* USART_CR3_OVER8 */
|
||||
}
|
||||
/**
|
||||
* @brief Configure the UART peripheral advanced features.
|
||||
* @param huart UART handle.
|
||||
* @retval None
|
||||
*/
|
||||
void UART_AdvFeatureConfig(UART_HandleTypeDef *huart)
|
||||
{
|
||||
/* Check whether the set of advanced features to configure is properly set */
|
||||
assert_param(IS_UART_ADVFEATURE_INIT(huart->AdvancedInit.AdvFeatureInit));
|
||||
|
||||
/* if required, configure auto Baud rate detection scheme */
|
||||
if (HAL_IS_BIT_SET(huart->AdvancedInit.AdvFeatureInit, UART_ADVFEATURE_AUTOBAUDRATE_INIT))
|
||||
{
|
||||
assert_param(IS_USART_AUTOBAUDRATE_DETECTION_INSTANCE(huart->Instance));
|
||||
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATE(huart->AdvancedInit.AutoBaudRateEnable));
|
||||
MODIFY_REG(huart->Instance->CR3, USART_CR3_ABREN, huart->AdvancedInit.AutoBaudRateEnable);
|
||||
/* set auto Baudrate detection parameters if detection is enabled */
|
||||
if (huart->AdvancedInit.AutoBaudRateEnable == UART_ADVFEATURE_AUTOBAUDRATE_ENABLE)
|
||||
{
|
||||
assert_param(IS_UART_ADVFEATURE_AUTOBAUDRATEMODE(huart->AdvancedInit.AutoBaudRateMode));
|
||||
MODIFY_REG(huart->Instance->CR3, USART_CR3_ABRMODE, huart->AdvancedInit.AutoBaudRateMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
2844
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_usart.c
Normal file
2844
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_usart.c
Normal file
@@ -0,0 +1,2844 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_usart.c
|
||||
* @author MCU Application Team
|
||||
* @brief USART HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Universal Synchronous/Asynchronous Receiver Transmitter
|
||||
* Peripheral (USART).
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral Control functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The USART HAL driver can be used as follows:
|
||||
|
||||
(#) Declare a USART_HandleTypeDef handle structure (eg. USART_HandleTypeDef husart).
|
||||
(#) Initialize the USART low level resources by implementing the HAL_USART_MspInit() API:
|
||||
(##) Enable the USARTx interface clock.
|
||||
(##) USART pins configuration:
|
||||
(+++) Enable the clock for the USART GPIOs.
|
||||
(+++) Configure the USART pins as alternate function pull-up.
|
||||
(##) NVIC configuration if you need to use interrupt process (HAL_USART_Transmit_IT(),
|
||||
HAL_USART_Receive_IT() and HAL_USART_TransmitReceive_IT() APIs):
|
||||
(+++) Configure the USARTx interrupt priority.
|
||||
(+++) Enable the NVIC USART IRQ handle.
|
||||
(##) DMA Configuration if you need to use DMA process (HAL_USART_Transmit_DMA()
|
||||
HAL_USART_Receive_DMA() and HAL_USART_TransmitReceive_DMA() APIs):
|
||||
(+++) Declare a DMA handle structure for the Tx/Rx channel.
|
||||
(+++) Enable the DMAx interface clock.
|
||||
(+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
|
||||
(+++) Configure the DMA Tx/Rx channel.
|
||||
(+++) Associate the initialized DMA handle to the USART DMA Tx/Rx handle.
|
||||
(+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx channel.
|
||||
(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
|
||||
(used for last byte sending completion detection in DMA non circular mode)
|
||||
|
||||
(#) Program the Baud Rate, Word Length, Stop Bit, Parity, Hardware
|
||||
flow control and Mode(Receiver/Transmitter) in the husart Init structure.
|
||||
|
||||
(#) Initialize the USART registers by calling the HAL_USART_Init() API:
|
||||
(++) These APIs configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
|
||||
by calling the customized HAL_USART_MspInit(&husart) API.
|
||||
|
||||
-@@- The specific USART interrupts (Transmission complete interrupt,
|
||||
RXNE interrupt and Error Interrupts) will be managed using the macros
|
||||
__HAL_USART_ENABLE_IT() and __HAL_USART_DISABLE_IT() inside the transmit and receive process.
|
||||
|
||||
(#) Three operation modes are available within this driver :
|
||||
|
||||
*** Polling mode IO operation ***
|
||||
=================================
|
||||
[..]
|
||||
(+) Send an amount of data in blocking mode using HAL_USART_Transmit()
|
||||
(+) Receive an amount of data in blocking mode using HAL_USART_Receive()
|
||||
|
||||
*** Interrupt mode IO operation ***
|
||||
===================================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode using HAL_USART_Transmit_IT()
|
||||
(+) At transmission end of transfer HAL_USART_TxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode using HAL_USART_Receive_IT()
|
||||
(+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_ErrorCallback
|
||||
|
||||
*** DMA mode IO operation ***
|
||||
==============================
|
||||
[..]
|
||||
(+) Send an amount of data in non blocking mode (DMA) using HAL_USART_Transmit_DMA()
|
||||
(+) At transmission end of half transfer HAL_USART_TxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_TxHalfCpltCallback
|
||||
(+) At transmission end of transfer HAL_USART_TxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_TxCpltCallback
|
||||
(+) Receive an amount of data in non blocking mode (DMA) using HAL_USART_Receive_DMA()
|
||||
(+) At reception end of half transfer HAL_USART_RxHalfCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_RxHalfCpltCallback
|
||||
(+) At reception end of transfer HAL_USART_RxCpltCallback is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_RxCpltCallback
|
||||
(+) In case of transfer Error, HAL_USART_ErrorCallback() function is executed and user can
|
||||
add his own code by customization of function pointer HAL_USART_ErrorCallback
|
||||
(+) Pause the DMA Transfer using HAL_USART_DMAPause()
|
||||
(+) Resume the DMA Transfer using HAL_USART_DMAResume()
|
||||
(+) Stop the DMA Transfer using HAL_USART_DMAStop()
|
||||
|
||||
*** USART HAL driver macros list ***
|
||||
=============================================
|
||||
[..]
|
||||
Below the list of most used macros in USART HAL driver.
|
||||
|
||||
(+) __HAL_USART_ENABLE: Enable the USART peripheral
|
||||
(+) __HAL_USART_DISABLE: Disable the USART peripheral
|
||||
(+) __HAL_USART_GET_FLAG : Check whether the specified USART flag is set or not
|
||||
(+) __HAL_USART_CLEAR_FLAG : Clear the specified USART pending flag
|
||||
(+) __HAL_USART_ENABLE_IT: Enable the specified USART interrupt
|
||||
(+) __HAL_USART_DISABLE_IT: Disable the specified USART interrupt
|
||||
|
||||
[..]
|
||||
(@) You can refer to the USART HAL driver header file for more useful macros
|
||||
|
||||
##### Callback registration #####
|
||||
==================================
|
||||
|
||||
[..]
|
||||
The compilation define USE_HAL_USART_REGISTER_CALLBACKS when set to 1
|
||||
allows the user to configure dynamically the driver callbacks.
|
||||
|
||||
[..]
|
||||
Use Function @ref HAL_USART_RegisterCallback() to register a user callback.
|
||||
Function @ref HAL_USART_RegisterCallback() allows to register following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) TxRxCpltCallback : Tx Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) MspInitCallback : USART MspInit.
|
||||
(+) MspDeInitCallback : USART MspDeInit.
|
||||
This function takes as parameters the HAL peripheral handle, the Callback ID
|
||||
and a pointer to the user callback function.
|
||||
|
||||
[..]
|
||||
Use function @ref HAL_USART_UnRegisterCallback() to reset a callback to the default
|
||||
weak (surcharged) function.
|
||||
@ref HAL_USART_UnRegisterCallback() takes as parameters the HAL peripheral handle,
|
||||
and the Callback ID.
|
||||
This function allows to reset following callbacks:
|
||||
(+) TxHalfCpltCallback : Tx Half Complete Callback.
|
||||
(+) TxCpltCallback : Tx Complete Callback.
|
||||
(+) RxHalfCpltCallback : Rx Half Complete Callback.
|
||||
(+) RxCpltCallback : Rx Complete Callback.
|
||||
(+) TxRxCpltCallback : Tx Rx Complete Callback.
|
||||
(+) ErrorCallback : Error Callback.
|
||||
(+) AbortCpltCallback : Abort Complete Callback.
|
||||
(+) MspInitCallback : USART MspInit.
|
||||
(+) MspDeInitCallback : USART MspDeInit.
|
||||
|
||||
[..]
|
||||
By default, after the @ref HAL_USART_Init() and when the state is HAL_USART_STATE_RESET
|
||||
all callbacks are set to the corresponding weak (surcharged) functions:
|
||||
examples @ref HAL_USART_TxCpltCallback(), @ref HAL_USART_RxHalfCpltCallback().
|
||||
Exception done for MspInit and MspDeInit functions that are respectively
|
||||
reset to the legacy weak (surcharged) functions in the @ref HAL_USART_Init()
|
||||
and @ref HAL_USART_DeInit() only when these callbacks are null (not registered beforehand).
|
||||
If not, MspInit or MspDeInit are not null, the @ref HAL_USART_Init() and @ref HAL_USART_DeInit()
|
||||
keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
|
||||
|
||||
[..]
|
||||
Callbacks can be registered/unregistered in HAL_USART_STATE_READY state only.
|
||||
Exception done MspInit/MspDeInit that can be registered/unregistered
|
||||
in HAL_USART_STATE_READY or HAL_USART_STATE_RESET state, thus registered (user)
|
||||
MspInit/DeInit callbacks can be used during the Init/DeInit.
|
||||
In that case first register the MspInit/MspDeInit user callbacks
|
||||
using @ref HAL_USART_RegisterCallback() before calling @ref HAL_USART_DeInit()
|
||||
or @ref HAL_USART_Init() function.
|
||||
|
||||
[..]
|
||||
When The compilation define USE_HAL_USART_REGISTER_CALLBACKS is set to 0 or
|
||||
not defined, the callback registration feature is not available
|
||||
and weak (surcharged) callbacks are used.
|
||||
|
||||
@endverbatim
|
||||
[..]
|
||||
(@) Additionnal remark: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
the possible USART frame formats are as listed in the following table:
|
||||
+-------------------------------------------------------------+
|
||||
| M bit | PCE bit | USART frame |
|
||||
|---------------------|---------------------------------------|
|
||||
| 0 | 0 | | SB | 8 bit data | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 0 | 1 | | SB | 7 bit data | PB | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 0 | | SB | 9 bit data | STB | |
|
||||
|---------|-----------|---------------------------------------|
|
||||
| 1 | 1 | | SB | 8 bit data | PB | STB | |
|
||||
+-------------------------------------------------------------+
|
||||
******************************************************************************
|
||||
* @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 USART USART
|
||||
* @brief HAL USART Synchronous module driver
|
||||
* @{
|
||||
*/
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @addtogroup USART_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
#define DUMMY_DATA 0xFFFFU
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @addtogroup USART_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
static void USART_EndRxTransfer(USART_HandleTypeDef *husart);
|
||||
static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart);
|
||||
static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart);
|
||||
static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart);
|
||||
static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart);
|
||||
static void USART_SetConfig(USART_HandleTypeDef *husart);
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
static void USART_EndTxTransfer(USART_HandleTypeDef *husart);
|
||||
static void USART_DMATransmitCplt(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMAError(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMAAbortOnError(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
static void USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
|
||||
#endif /* DMA1 or DMA */
|
||||
static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup USART_Exported_Functions USART Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup USART_Exported_Functions_Group1 USART Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to initialize the USART
|
||||
in asynchronous and in synchronous modes.
|
||||
(+) For the asynchronous mode only these parameters can be configured:
|
||||
(++) Baud Rate
|
||||
(++) Word Length
|
||||
(++) Stop Bit
|
||||
(++) Parity: If the parity is enabled, then the MSB bit of the data written
|
||||
in the data register is transmitted but is changed by the parity bit.
|
||||
Depending on the frame length defined by the M bit (8-bits or 9-bits),
|
||||
please refer to Reference manual for possible USART frame formats.
|
||||
(++) USART polarity
|
||||
(++) USART phase
|
||||
(++) USART LastBit
|
||||
(++) Receiver/transmitter modes
|
||||
|
||||
[..]
|
||||
The HAL_USART_Init() function follows the USART synchronous configuration
|
||||
procedures (details for the procedures are available in reference manuals).
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the USART mode according to the specified
|
||||
* parameters in the USART_InitTypeDef and initialize the associated handle.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Check the USART handle allocation */
|
||||
if (husart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_USART_INSTANCE(husart->Instance));
|
||||
|
||||
if (husart->State == HAL_USART_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
husart->Lock = HAL_UNLOCKED;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
USART_InitCallbacksToDefault(husart);
|
||||
|
||||
if (husart->MspInitCallback == NULL)
|
||||
{
|
||||
husart->MspInitCallback = HAL_USART_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
husart->MspInitCallback(husart);
|
||||
#else
|
||||
/* Init the low level hardware : GPIO, CLOCK */
|
||||
HAL_USART_MspInit(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
husart->State = HAL_USART_STATE_BUSY;
|
||||
|
||||
/* Set the USART Communication parameters */
|
||||
USART_SetConfig(husart);
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_USART_ENABLE(husart);
|
||||
|
||||
/* Initialize the USART state */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the USART peripheral.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_DeInit(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Check the USART handle allocation */
|
||||
if (husart == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_USART_INSTANCE(husart->Instance));
|
||||
|
||||
husart->State = HAL_USART_STATE_BUSY;
|
||||
|
||||
/* Disable the Peripheral */
|
||||
__HAL_USART_DISABLE(husart);
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
if (husart->MspDeInitCallback == NULL)
|
||||
{
|
||||
husart->MspDeInitCallback = HAL_USART_MspDeInit;
|
||||
}
|
||||
/* DeInit the low level hardware */
|
||||
husart->MspDeInitCallback(husart);
|
||||
#else
|
||||
/* DeInit the low level hardware */
|
||||
HAL_USART_MspDeInit(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART MSP Init.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_MspInit(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART MSP DeInit.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_MspDeInit(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_MspDeInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User USART Callback
|
||||
* To be used instead of the weak predefined callback
|
||||
* @param husart usart handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval HAL status
|
||||
+ */
|
||||
HAL_StatusTypeDef HAL_USART_RegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID, pUSART_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if (pCallback == NULL)
|
||||
{
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_USART_TX_HALFCOMPLETE_CB_ID :
|
||||
husart->TxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_TX_COMPLETE_CB_ID :
|
||||
husart->TxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_RX_HALFCOMPLETE_CB_ID :
|
||||
husart->RxHalfCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_RX_COMPLETE_CB_ID :
|
||||
husart->RxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_TX_RX_COMPLETE_CB_ID :
|
||||
husart->TxRxCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_ERROR_CB_ID :
|
||||
husart->ErrorCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_ABORT_COMPLETE_CB_ID :
|
||||
husart->AbortCpltCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPINIT_CB_ID :
|
||||
husart->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPDEINIT_CB_ID :
|
||||
husart->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (husart->State == HAL_USART_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_USART_MSPINIT_CB_ID :
|
||||
husart->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPDEINIT_CB_ID :
|
||||
husart->MspDeInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister an USART Callback
|
||||
* USART callaback is redirected to the weak predefined callback
|
||||
* @param husart uart handle
|
||||
* @param CallbackID ID of the callback to be unregistered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_USART_TX_HALFCOMPLETE_CB_ID Tx Half Complete Callback ID
|
||||
* @arg @ref HAL_USART_TX_COMPLETE_CB_ID Tx Complete Callback ID
|
||||
* @arg @ref HAL_USART_RX_HALFCOMPLETE_CB_ID Rx Half Complete Callback ID
|
||||
* @arg @ref HAL_USART_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_USART_TX_RX_COMPLETE_CB_ID Rx Complete Callback ID
|
||||
* @arg @ref HAL_USART_ERROR_CB_ID Error Callback ID
|
||||
* @arg @ref HAL_USART_ABORT_COMPLETE_CB_ID Abort Complete Callback ID
|
||||
* @arg @ref HAL_USART_MSPINIT_CB_ID MspInit Callback ID
|
||||
* @arg @ref HAL_USART_MSPDEINIT_CB_ID MspDeInit Callback ID
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_UnRegisterCallback(USART_HandleTypeDef *husart, HAL_USART_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_USART_TX_HALFCOMPLETE_CB_ID :
|
||||
husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_TX_COMPLETE_CB_ID :
|
||||
husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_RX_HALFCOMPLETE_CB_ID :
|
||||
husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_RX_COMPLETE_CB_ID :
|
||||
husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_TX_RX_COMPLETE_CB_ID :
|
||||
husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_ERROR_CB_ID :
|
||||
husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_ABORT_COMPLETE_CB_ID :
|
||||
husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPINIT_CB_ID :
|
||||
husart->MspInitCallback = HAL_USART_MspInit; /* Legacy weak MspInitCallback */
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPDEINIT_CB_ID :
|
||||
husart->MspDeInitCallback = HAL_USART_MspDeInit; /* Legacy weak MspDeInitCallback */
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (husart->State == HAL_USART_STATE_RESET)
|
||||
{
|
||||
switch (CallbackID)
|
||||
{
|
||||
case HAL_USART_MSPINIT_CB_ID :
|
||||
husart->MspInitCallback = HAL_USART_MspInit;
|
||||
break;
|
||||
|
||||
case HAL_USART_MSPDEINIT_CB_ID :
|
||||
husart->MspDeInitCallback = HAL_USART_MspDeInit;
|
||||
break;
|
||||
|
||||
default :
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update the error code */
|
||||
husart->ErrorCode |= HAL_USART_ERROR_INVALID_CALLBACK;
|
||||
|
||||
/* Return error status */
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USART_Exported_Functions_Group2 IO operation functions
|
||||
* @brief USART Transmit and Receive functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### IO operation functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the USART synchronous
|
||||
data transfers.
|
||||
|
||||
[..]
|
||||
The USART supports master mode only: it cannot receive or send data related to an input
|
||||
clock (SCLK is always an output).
|
||||
|
||||
(#) 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 API's return the HAL status.
|
||||
The end of the data processing will be indicated through the
|
||||
dedicated USART IRQ when using Interrupt mode or the DMA IRQ when
|
||||
using DMA mode.
|
||||
The HAL_USART_TxCpltCallback(), HAL_USART_RxCpltCallback() and HAL_USART_TxRxCpltCallback()
|
||||
user callbacks
|
||||
will be executed respectively at the end of the transmit or Receive process
|
||||
The HAL_USART_ErrorCallback() user callback will be executed when a communication
|
||||
error is detected
|
||||
|
||||
(#) Blocking mode APIs are :
|
||||
(++) HAL_USART_Transmit() in simplex mode
|
||||
(++) HAL_USART_Receive() in full duplex receive only
|
||||
(++) HAL_USART_TransmitReceive() in full duplex mode
|
||||
|
||||
(#) Non Blocking mode APIs with Interrupt are :
|
||||
(++) HAL_USART_Transmit_IT()in simplex mode
|
||||
(++) HAL_USART_Receive_IT() in full duplex receive only
|
||||
(++) HAL_USART_TransmitReceive_IT() in full duplex mode
|
||||
(++) HAL_USART_IRQHandler()
|
||||
|
||||
(#) Non Blocking mode functions with DMA are :
|
||||
(++) HAL_USART_Transmit_DMA()in simplex mode
|
||||
(++) HAL_USART_Receive_DMA() in full duplex receive only
|
||||
(++) HAL_USART_TransmitReceive_DMA() in full duplex mode
|
||||
(++) HAL_USART_DMAPause()
|
||||
(++) HAL_USART_DMAResume()
|
||||
(++) HAL_USART_DMAStop()
|
||||
|
||||
(#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
|
||||
(++) HAL_USART_TxHalfCpltCallback()
|
||||
(++) HAL_USART_TxCpltCallback()
|
||||
(++) HAL_USART_RxHalfCpltCallback()
|
||||
(++) HAL_USART_RxCpltCallback()
|
||||
(++) HAL_USART_ErrorCallback()
|
||||
(++) HAL_USART_TxRxCpltCallback()
|
||||
|
||||
(#) Non-Blocking mode transfers could be aborted using Abort API's :
|
||||
(++) HAL_USART_Abort()
|
||||
(++) HAL_USART_Abort_IT()
|
||||
|
||||
(#) For Abort services based on interrupts (HAL_USART_Abort_IT), a Abort Complete Callbacks is provided:
|
||||
(++) HAL_USART_AbortCpltCallback()
|
||||
|
||||
(#) In Non-Blocking mode transfers, possible errors are split into 2 categories.
|
||||
Errors are handled as follows :
|
||||
(++) Error is considered as Recoverable and non blocking : Transfer could go till end, but error severity is
|
||||
to be evaluated by user : this concerns Frame Error, Parity Error or Noise Error in Interrupt mode reception .
|
||||
Received character is then retrieved and stored in Rx buffer, Error code is set to allow user to identify error type,
|
||||
and HAL_USART_ErrorCallback() user callback is executed. Transfer is kept ongoing on USART side.
|
||||
If user wants to abort it, Abort services should be called by user.
|
||||
(++) Error is considered as Blocking : Transfer could not be completed properly and is aborted.
|
||||
This concerns Overrun Error In Interrupt mode reception and all errors in DMA mode.
|
||||
Error code is set to allow user to identify error type, and HAL_USART_ErrorCallback() user callback is executed.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Simplex Send an amount of data in blocking mode.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pTxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @param Timeout Timeout duration.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_TX;
|
||||
|
||||
/* Init tickstart for timeout management */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
husart->TxXferSize = Size;
|
||||
husart->TxXferCount = Size;
|
||||
while (husart->TxXferCount > 0U)
|
||||
{
|
||||
husart->TxXferCount--;
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
/* Wait for TC flag in order to write data in DR */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pTxData;
|
||||
husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
pTxData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTxData += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
husart->Instance->DR = (*pTxData++ & (uint8_t)0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TC, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Receive an amount of data in blocking mode.
|
||||
* @note To receive synchronous data, dummy data are simultaneously transmitted.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pRxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pRxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @param Timeout Timeout duration.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Receive(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_RX;
|
||||
|
||||
/* Init tickstart for timeout management */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
husart->RxXferSize = Size;
|
||||
husart->RxXferCount = Size;
|
||||
/* Check the remain data to be received */
|
||||
while (husart->RxXferCount > 0U)
|
||||
{
|
||||
husart->RxXferCount--;
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
/* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
/* Send dummy byte in order to generate clock */
|
||||
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
|
||||
|
||||
/* Wait for RXNE Flag */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pRxData ;
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
|
||||
pRxData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
|
||||
pRxData += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait until TXE flag is set to send dummy byte in order to generate the clock for the slave to send data */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/* Send Dummy Byte in order to generate clock */
|
||||
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
|
||||
|
||||
/* Wait until RXNE flag is set to receive the byte */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
/* Receive data */
|
||||
*pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Receive data */
|
||||
*pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Send and Receive an amount of data in full-duplex mode (blocking mode).
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pTxData and through pRxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to TX data buffer (u8 or u16 data elements).
|
||||
* @param pRxData Pointer to RX data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent (same amount to be received).
|
||||
* @param Timeout Timeout duration
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_TransmitReceive(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
uint32_t tickstart = 0U;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_RX;
|
||||
|
||||
/* Init tickstart for timeout management */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
husart->RxXferSize = Size;
|
||||
husart->TxXferSize = Size;
|
||||
husart->TxXferCount = Size;
|
||||
husart->RxXferCount = Size;
|
||||
|
||||
/* Check the remain data to be received */
|
||||
while (husart->TxXferCount > 0U)
|
||||
{
|
||||
husart->TxXferCount--;
|
||||
husart->RxXferCount--;
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
/* Wait for TC flag in order to write data in DR */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pTxData;
|
||||
husart->Instance->DR = (*tmp & (uint16_t)0x01FF);
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
pTxData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTxData += 1U;
|
||||
}
|
||||
|
||||
/* Wait for RXNE Flag */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
tmp = (uint16_t *) pRxData ;
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
|
||||
pRxData += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
|
||||
pRxData += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for TC flag in order to write data in DR */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_TXE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
husart->Instance->DR = (*pTxData++ & (uint8_t)0x00FF);
|
||||
|
||||
/* Wait for RXNE Flag */
|
||||
if (USART_WaitOnFlagUntilTimeout(husart, USART_FLAG_RXNE, RESET, tickstart, Timeout) != HAL_OK)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
/* Receive data */
|
||||
*pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Receive data */
|
||||
*pRxData++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Simplex Send an amount of data in non-blocking mode.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pTxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @retval HAL status
|
||||
* @note The USART errors are not managed to avoid the overrun error.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Transmit_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pTxBuffPtr = pTxData;
|
||||
husart->TxXferSize = Size;
|
||||
husart->TxXferCount = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_TX;
|
||||
|
||||
/* The USART Error Interrupts: (Frame error, Noise error, Overrun error)
|
||||
are not managed by the USART transmit process to avoid the overrun interrupt
|
||||
when the USART mode is configured for transmit and receive "USART_MODE_TX_RX"
|
||||
to benefit for the frame error and noise interrupts the USART mode should be
|
||||
configured only for transmit "USART_MODE_TX"
|
||||
The __HAL_USART_ENABLE_IT(husart, USART_IT_ERR) can be used to enable the Frame error,
|
||||
Noise error interrupt */
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the USART Transmit Data Register Empty Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Simplex Receive an amount of data in non-blocking mode.
|
||||
* @note To receive synchronous data, dummy data are simultaneously transmitted.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pRxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pRxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Receive_IT(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pRxBuffPtr = pRxData;
|
||||
husart->RxXferSize = Size;
|
||||
husart->RxXferCount = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_RX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the USART Parity Error and Data Register not empty Interrupts */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE);
|
||||
|
||||
/* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Send dummy byte in order to generate the clock for the slave to send data */
|
||||
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Send and Receive an amount of data in full-duplex mode (non-blocking).
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pTxData and through pRxData.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to TX data buffer (u8 or u16 data elements).
|
||||
* @param pRxData Pointer to RX data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent (same amount to be received).
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_TransmitReceive_IT(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pRxBuffPtr = pRxData;
|
||||
husart->RxXferSize = Size;
|
||||
husart->RxXferCount = Size;
|
||||
husart->pTxBuffPtr = pTxData;
|
||||
husart->TxXferSize = Size;
|
||||
husart->TxXferCount = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_TX_RX;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the USART Data Register not empty Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
|
||||
|
||||
/* Enable the USART Parity Error Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the USART Transmit Data Register Empty Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief Simplex Send an amount of data in DMA mode.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 provided through pTxData.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be sent.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Transmit_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pTxBuffPtr = pTxData;
|
||||
husart->TxXferSize = Size;
|
||||
husart->TxXferCount = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_TX;
|
||||
|
||||
/* Set the USART DMA transfer complete callback */
|
||||
husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
|
||||
|
||||
/* Set the USART DMA Half transfer complete callback */
|
||||
husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
husart->hdmatx->XferErrorCallback = USART_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the USART transmit DMA channel */
|
||||
tmp = (uint32_t *)&pTxData;
|
||||
HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->DR, Size);
|
||||
|
||||
/* Clear the TC flag in the SR register by writing 0 to it */
|
||||
__HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Receive an amount of data in DMA mode.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the received data is handled as a set of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pRxData.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pRxData Pointer to data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received.
|
||||
* @retval HAL status
|
||||
* @note The USART DMA transmit channel must be configured in order to generate the clock for the slave.
|
||||
* @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Receive_DMA(USART_HandleTypeDef *husart, uint8_t *pRxData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pRxBuffPtr = pRxData;
|
||||
husart->RxXferSize = Size;
|
||||
husart->pTxBuffPtr = pRxData;
|
||||
husart->TxXferSize = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_RX;
|
||||
|
||||
/* Set the USART DMA Rx transfer complete callback */
|
||||
husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
|
||||
|
||||
/* Set the USART DMA Half transfer complete callback */
|
||||
husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
|
||||
|
||||
/* Set the USART DMA Rx transfer error callback */
|
||||
husart->hdmarx->XferErrorCallback = USART_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Set the USART Tx DMA transfer complete callback as NULL because the communication closing
|
||||
is performed in DMA reception complete callback */
|
||||
husart->hdmatx->XferHalfCpltCallback = NULL;
|
||||
husart->hdmatx->XferCpltCallback = NULL;
|
||||
|
||||
/* Set the DMA error callback */
|
||||
husart->hdmatx->XferErrorCallback = USART_DMAError;
|
||||
|
||||
/* Set the DMA AbortCpltCallback */
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the USART receive DMA channel */
|
||||
tmp = (uint32_t *)&pRxData;
|
||||
HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t *)tmp, Size);
|
||||
|
||||
/* Enable the USART transmit DMA channel: the transmit channel is used in order
|
||||
to generate in the non-blocking mode the clock to the slave device,
|
||||
this mode isn't a simplex receive mode but a full-duplex receive one */
|
||||
HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->DR, Size);
|
||||
|
||||
/* Clear the Overrun flag just before enabling the DMA Rx request: mandatory for the second transfer */
|
||||
__HAL_USART_CLEAR_OREFLAG(husart);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the USART Parity Error Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Enable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Transmit Receive an amount of data in DMA mode.
|
||||
* @note When USART parity is not enabled (PCE = 0), and Word Length is configured to 9 bits (M=1),
|
||||
* the sent data and the received data are handled as sets of u16. In this case, Size must indicate the number
|
||||
* of u16 available through pTxData and through pRxData.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param pTxData Pointer to TX data buffer (u8 or u16 data elements).
|
||||
* @param pRxData Pointer to RX data buffer (u8 or u16 data elements).
|
||||
* @param Size Amount of data elements (u8 or u16) to be received/sent.
|
||||
* @note When the USART parity is enabled (PCE = 1) the data received contain the parity bit.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_TransmitReceive_DMA(USART_HandleTypeDef *husart, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
|
||||
{
|
||||
uint32_t *tmp;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_READY)
|
||||
{
|
||||
if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
husart->pRxBuffPtr = pRxData;
|
||||
husart->RxXferSize = Size;
|
||||
husart->pTxBuffPtr = pTxData;
|
||||
husart->TxXferSize = Size;
|
||||
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
husart->State = HAL_USART_STATE_BUSY_TX_RX;
|
||||
|
||||
/* Set the USART DMA Rx transfer complete callback */
|
||||
husart->hdmarx->XferCpltCallback = USART_DMAReceiveCplt;
|
||||
|
||||
/* Set the USART DMA Half transfer complete callback */
|
||||
husart->hdmarx->XferHalfCpltCallback = USART_DMARxHalfCplt;
|
||||
|
||||
/* Set the USART DMA Tx transfer complete callback */
|
||||
husart->hdmatx->XferCpltCallback = USART_DMATransmitCplt;
|
||||
|
||||
/* Set the USART DMA Half transfer complete callback */
|
||||
husart->hdmatx->XferHalfCpltCallback = USART_DMATxHalfCplt;
|
||||
|
||||
/* Set the USART DMA Tx transfer error callback */
|
||||
husart->hdmatx->XferErrorCallback = USART_DMAError;
|
||||
|
||||
/* Set the USART DMA Rx transfer error callback */
|
||||
husart->hdmarx->XferErrorCallback = USART_DMAError;
|
||||
|
||||
/* Set the DMA abort callback */
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Enable the USART receive DMA channel */
|
||||
tmp = (uint32_t *)&pRxData;
|
||||
HAL_DMA_Start_IT(husart->hdmarx, (uint32_t)&husart->Instance->DR, *(uint32_t *)tmp, Size);
|
||||
|
||||
/* Enable the USART transmit DMA channel */
|
||||
tmp = (uint32_t *)&pTxData;
|
||||
HAL_DMA_Start_IT(husart->hdmatx, *(uint32_t *)tmp, (uint32_t)&husart->Instance->DR, Size);
|
||||
|
||||
/* Clear the TC flag in the SR register by writing 0 to it */
|
||||
__HAL_USART_CLEAR_FLAG(husart, USART_FLAG_TC);
|
||||
|
||||
/* Clear the Overrun flag: mandatory for the second transfer in circular mode */
|
||||
__HAL_USART_CLEAR_OREFLAG(husart);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
/* Enable the USART Parity Error Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Enable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Enable the DMA transfer for the receiver request by setting the DMAR bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Enable the DMA transfer for transmit request by setting the DMAT bit
|
||||
in the USART CR3 register */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Pauses the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_DMAPause(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
/* Disable the USART DMA Tx request */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resumes the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_DMAResume(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(husart);
|
||||
|
||||
/* Enable the USART DMA Tx request */
|
||||
SET_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stops the DMA Transfer.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_DMAStop(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
/* The Lock is not implemented on this API to allow the user application
|
||||
to call the HAL USART API under callbacks HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback():
|
||||
when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
|
||||
and the correspond call back is executed HAL_USART_TxCpltCallback() / HAL_USART_RxCpltCallback()
|
||||
*/
|
||||
|
||||
/* Stop USART DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
USART_EndTxTransfer(husart);
|
||||
|
||||
/* Abort the USART DMA Tx channel */
|
||||
if (husart->hdmatx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(husart->hdmatx);
|
||||
}
|
||||
|
||||
/* Disable the USART Tx DMA request */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
}
|
||||
|
||||
/* Stop USART DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
USART_EndRxTransfer(husart);
|
||||
|
||||
/* Abort the USART DMA Rx channel */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
HAL_DMA_Abort(husart->hdmarx);
|
||||
}
|
||||
|
||||
/* Disable the USART Rx DMA request */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfer (blocking mode).
|
||||
* @param husart USART handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
|
||||
* as described by TransferType parameter) started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP 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_USART_Abort(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the USART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the USART DMA Tx channel : use blocking DMA Abort API (no callback) */
|
||||
if (husart->hdmatx != NULL)
|
||||
{
|
||||
/* Set the USART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(husart->hdmatx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the USART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the USART DMA Rx channel : use blocking DMA Abort API (no callback) */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the USART DMA Abort callback to Null.
|
||||
No call back execution at end of DMA abort procedure */
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
HAL_DMA_Abort(husart->hdmarx);
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
husart->TxXferCount = 0x00U;
|
||||
husart->RxXferCount = 0x00U;
|
||||
|
||||
/* Restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Reset Handle ErrorCode to No Error */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort ongoing transfer (Interrupt mode).
|
||||
* @param husart USART handle.
|
||||
* @note This procedure could be used for aborting any ongoing transfer (either Tx or Rx,
|
||||
* as described by TransferType parameter) started in Interrupt or DMA mode.
|
||||
* This procedure performs following operations :
|
||||
* - Disable PPP 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_USART_Abort_IT(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint32_t AbortCplt = 0x01U;
|
||||
|
||||
/* Disable TXEIE, TCIE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE | USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* If DMA Tx and/or DMA Rx Handles are associated to USART Handle, DMA Abort complete callbacks should be initialised
|
||||
before any call to DMA Abort functions */
|
||||
/* DMA Tx Handle is valid */
|
||||
if (husart->hdmatx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if USART DMA Tx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
husart->hdmatx->XferAbortCallback = USART_DMATxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
/* DMA Rx Handle is valid */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
/* Set DMA Abort Complete callback if USART DMA Rx request if enabled.
|
||||
Otherwise, set it to NULL */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
husart->hdmarx->XferAbortCallback = USART_DMARxAbortCallback;
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the USART DMA Tx request if enabled */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT))
|
||||
{
|
||||
/* Disable DMA Tx at USART level */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Abort the USART DMA Tx channel : use non blocking DMA Abort API (callback) */
|
||||
if (husart->hdmatx != NULL)
|
||||
{
|
||||
/* USART Tx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA TX */
|
||||
if (HAL_DMA_Abort_IT(husart->hdmatx) != HAL_OK)
|
||||
{
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the USART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the USART DMA Rx channel : use non blocking DMA Abort API (callback) */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
/* USART Rx DMA Abort callback has already been initialised :
|
||||
will lead to call HAL_USART_AbortCpltCallback() at end of DMA abort procedure */
|
||||
|
||||
/* Abort DMA RX */
|
||||
if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
|
||||
{
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
AbortCplt = 0x01U;
|
||||
}
|
||||
else
|
||||
{
|
||||
AbortCplt = 0x00U;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* if no DMA abort complete callback execution is required => call user Abort Complete callback */
|
||||
if (AbortCplt == 0x01U)
|
||||
{
|
||||
/* Reset Tx and Rx transfer counters */
|
||||
husart->TxXferCount = 0x00U;
|
||||
husart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset errorCode */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
|
||||
/* Restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* As no DMA to be aborted, call directly user Abort complete callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Complete Callback */
|
||||
husart->AbortCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Abort Complete Callback */
|
||||
HAL_USART_AbortCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles USART interrupt request.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_USART_IRQHandler(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint32_t isrflags = READ_REG(husart->Instance->SR);
|
||||
uint32_t cr1its = READ_REG(husart->Instance->CR1);
|
||||
uint32_t cr3its = READ_REG(husart->Instance->CR3);
|
||||
uint32_t errorflags = 0x00U;
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
uint32_t dmarequest = 0x00U;
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/* If no error occurs */
|
||||
errorflags = (isrflags & (uint32_t)(USART_SR_PE | USART_SR_FE | USART_SR_ORE | USART_SR_NE));
|
||||
if (errorflags == RESET)
|
||||
{
|
||||
/* USART in mode Receiver -------------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_BUSY_RX)
|
||||
{
|
||||
USART_Receive_IT(husart);
|
||||
}
|
||||
else
|
||||
{
|
||||
USART_TransmitReceive_IT(husart);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* If some errors occur */
|
||||
if ((errorflags != RESET) && (((cr3its & USART_CR3_EIE) != RESET) || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)))
|
||||
{
|
||||
/* USART parity error interrupt occurred ----------------------------------*/
|
||||
if (((isrflags & USART_SR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET))
|
||||
{
|
||||
husart->ErrorCode |= HAL_USART_ERROR_PE;
|
||||
}
|
||||
|
||||
/* USART noise error interrupt occurred --------------------------------*/
|
||||
if (((isrflags & USART_SR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
husart->ErrorCode |= HAL_USART_ERROR_NE;
|
||||
}
|
||||
|
||||
/* USART frame error interrupt occurred --------------------------------*/
|
||||
if (((isrflags & USART_SR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
husart->ErrorCode |= HAL_USART_ERROR_FE;
|
||||
}
|
||||
|
||||
/* USART Over-Run interrupt occurred -----------------------------------*/
|
||||
if (((isrflags & USART_SR_ORE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET))
|
||||
{
|
||||
husart->ErrorCode |= HAL_USART_ERROR_ORE;
|
||||
}
|
||||
|
||||
if (husart->ErrorCode != HAL_USART_ERROR_NONE)
|
||||
{
|
||||
/* USART in mode Receiver -----------------------------------------------*/
|
||||
if (((isrflags & USART_SR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET))
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_BUSY_RX)
|
||||
{
|
||||
USART_Receive_IT(husart);
|
||||
}
|
||||
else
|
||||
{
|
||||
USART_TransmitReceive_IT(husart);
|
||||
}
|
||||
}
|
||||
/* If Overrun error occurs, or if any error occurs in DMA mode reception,
|
||||
consider error as blocking */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
if (((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET) || dmarequest)
|
||||
#else
|
||||
if ((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET)
|
||||
#endif /* DMA1 or DMA */
|
||||
{
|
||||
/* Set the USART state ready to be able to start again the process,
|
||||
Disable Rx Interrupts, and disable Rx DMA request, if ongoing */
|
||||
USART_EndRxTransfer(husart);
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/* Disable the USART DMA Rx request if enabled */
|
||||
if (HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR))
|
||||
{
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
|
||||
/* Abort the USART DMA Rx channel */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
/* Set the USART DMA Abort callback :
|
||||
will lead to call HAL_USART_ErrorCallback() at end of DMA abort procedure */
|
||||
husart->hdmarx->XferAbortCallback = USART_DMAAbortOnError;
|
||||
|
||||
if (HAL_DMA_Abort_IT(husart->hdmarx) != HAL_OK)
|
||||
{
|
||||
/* Call Directly XferAbortCallback function in case of error */
|
||||
husart->hdmarx->XferAbortCallback(husart->hdmarx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call user error callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Error Callback */
|
||||
husart->ErrorCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Error Callback */
|
||||
HAL_USART_ErrorCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* DMA1 or DMA */
|
||||
/* Call user error callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Error Callback */
|
||||
husart->ErrorCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Error Callback */
|
||||
HAL_USART_ErrorCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Call user error callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Error Callback */
|
||||
husart->ErrorCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Error Callback */
|
||||
HAL_USART_ErrorCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* USART in mode Transmitter -----------------------------------------------*/
|
||||
if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET))
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_BUSY_TX)
|
||||
{
|
||||
USART_Transmit_IT(husart);
|
||||
}
|
||||
else
|
||||
{
|
||||
USART_TransmitReceive_IT(husart);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* USART in mode Transmitter (transmission end) ----------------------------*/
|
||||
if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET))
|
||||
{
|
||||
USART_EndTransmit_IT(husart);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Transfer completed callbacks.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_TxCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_TxCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx Half Transfer completed callbacks.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_TxHalfCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_TxHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Transfer completed callbacks.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_RxCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_RxCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Rx Half Transfer completed callbacks.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_RxHalfCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_RxHalfCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Tx/Rx Transfers completed callback for the non-blocking process.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_TxRxCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_TxRxCpltCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART error callbacks.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_ErrorCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_ErrorCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART Abort Complete callback.
|
||||
* @param husart USART handle.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_USART_AbortCpltCallback(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(husart);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_USART_AbortCpltCallback can be implemented in the user file.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USART_Exported_Functions_Group3 Peripheral State and Errors functions
|
||||
* @brief USART State and Errors functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Peripheral State and Errors functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to return the State of
|
||||
USART communication
|
||||
process, return Peripheral Errors occurred during communication process
|
||||
(+) HAL_USART_GetState() API can be helpful to check in run-time the state
|
||||
of the USART peripheral.
|
||||
(+) HAL_USART_GetError() check in run-time errors that could be occurred during
|
||||
communication.
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Returns the USART state.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_USART_StateTypeDef HAL_USART_GetState(USART_HandleTypeDef *husart)
|
||||
{
|
||||
return husart->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the USART error code
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART.
|
||||
* @retval USART Error Code
|
||||
*/
|
||||
uint32_t HAL_USART_GetError(USART_HandleTypeDef *husart)
|
||||
{
|
||||
return husart->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup USART_Private_Functions USART Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the callbacks to their default values.
|
||||
* @param husart USART handle.
|
||||
* @retval none
|
||||
*/
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
void USART_InitCallbacksToDefault(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Init the USART Callback settings */
|
||||
husart->TxHalfCpltCallback = HAL_USART_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
|
||||
husart->TxCpltCallback = HAL_USART_TxCpltCallback; /* Legacy weak TxCpltCallback */
|
||||
husart->RxHalfCpltCallback = HAL_USART_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
|
||||
husart->RxCpltCallback = HAL_USART_RxCpltCallback; /* Legacy weak RxCpltCallback */
|
||||
husart->TxRxCpltCallback = HAL_USART_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
|
||||
husart->ErrorCallback = HAL_USART_ErrorCallback; /* Legacy weak ErrorCallback */
|
||||
husart->AbortCpltCallback = HAL_USART_AbortCpltCallback; /* Legacy weak AbortCpltCallback */
|
||||
}
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
/* DMA Normal mode */
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
husart->TxXferCount = 0U;
|
||||
if (husart->State == HAL_USART_STATE_BUSY_TX)
|
||||
{
|
||||
/* Disable the DMA transfer for transmit request by resetting the DMAT bit
|
||||
in the USART CR3 register */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
/* Enable the USART Transmit Complete Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_TCIE);
|
||||
}
|
||||
}
|
||||
/* DMA Circular mode */
|
||||
else
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_BUSY_TX)
|
||||
{
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Complete Callback */
|
||||
husart->TxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Complete Callback */
|
||||
HAL_USART_TxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART transmit process half 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 USART_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Half Complete Callback */
|
||||
husart->TxHalfCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Half Complete Callback */
|
||||
HAL_USART_TxHalfCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
/* DMA Normal mode */
|
||||
if ((hdma->Instance->CCR & DMA_CCR_CIRC) == 0U)
|
||||
{
|
||||
husart->RxXferCount = 0x00U;
|
||||
|
||||
/* Disable RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* Disable the DMA transfer for the Transmit/receiver request by clearing the DMAT/DMAR bit
|
||||
in the USART CR3 register */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* The USART state is HAL_USART_STATE_BUSY_RX */
|
||||
if (husart->State == HAL_USART_STATE_BUSY_RX)
|
||||
{
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx Complete Callback */
|
||||
husart->RxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Rx Complete Callback */
|
||||
HAL_USART_RxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
/* The USART state is HAL_USART_STATE_BUSY_TX_RX */
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Rx Complete Callback */
|
||||
husart->TxRxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Rx Complete Callback */
|
||||
HAL_USART_TxRxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
/* DMA circular mode */
|
||||
else
|
||||
{
|
||||
if (husart->State == HAL_USART_STATE_BUSY_RX)
|
||||
{
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx Complete Callback */
|
||||
husart->RxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Rx Complete Callback */
|
||||
HAL_USART_RxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
/* The USART state is HAL_USART_STATE_BUSY_TX_RX */
|
||||
else
|
||||
{
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Rx Complete Callback */
|
||||
husart->TxRxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Rx Complete Callback */
|
||||
HAL_USART_TxRxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART receive process half 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 USART_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx Half Complete Callback */
|
||||
husart->RxHalfCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Rx Half Complete Callback */
|
||||
HAL_USART_RxHalfCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMAError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t dmarequest = 0x00U;
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
husart->RxXferCount = 0x00U;
|
||||
husart->TxXferCount = 0x00U;
|
||||
|
||||
/* Stop USART DMA Tx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAT);
|
||||
if ((husart->State == HAL_USART_STATE_BUSY_TX) && dmarequest)
|
||||
{
|
||||
USART_EndTxTransfer(husart);
|
||||
}
|
||||
|
||||
/* Stop USART DMA Rx request if ongoing */
|
||||
dmarequest = HAL_IS_BIT_SET(husart->Instance->CR3, USART_CR3_DMAR);
|
||||
if ((husart->State == HAL_USART_STATE_BUSY_RX) && dmarequest)
|
||||
{
|
||||
USART_EndRxTransfer(husart);
|
||||
}
|
||||
|
||||
husart->ErrorCode |= HAL_USART_ERROR_DMA;
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Error Callback */
|
||||
husart->ErrorCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Error Callback */
|
||||
HAL_USART_ErrorCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief This function handles USART Communication Timeout.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @param Flag specifies the USART flag to check.
|
||||
* @param Status The new Flag status (SET or RESET).
|
||||
* @param Tickstart Tick start value.
|
||||
* @param Timeout Timeout duration.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef USART_WaitOnFlagUntilTimeout(USART_HandleTypeDef *husart, uint32_t Flag, FlagStatus Status, uint32_t Tickstart, uint32_t Timeout)
|
||||
{
|
||||
/* Wait until flag is set */
|
||||
while ((__HAL_USART_GET_FLAG(husart, Flag) ? SET : RESET) == Status)
|
||||
{
|
||||
/* Check for the Timeout */
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if ((Timeout == 0U) || ((HAL_GetTick() - Tickstart) > Timeout))
|
||||
{
|
||||
/* Disable the USART Transmit Complete Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
/* Disable the USART RXNE Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
|
||||
|
||||
/* Disable the USART Parity Error Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(husart);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief End ongoing Tx transfer on USART peripheral (following error detection or Transmit completion).
|
||||
* @param husart USART handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void USART_EndTxTransfer(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Disable TXEIE and TCIE interrupts */
|
||||
CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
|
||||
|
||||
/* At end of Tx process, restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
/**
|
||||
* @brief End ongoing Rx transfer on USART peripheral (following error detection or Reception completion).
|
||||
* @param husart USART handle.
|
||||
* @retval None
|
||||
*/
|
||||
static void USART_EndRxTransfer(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Disable RXNE, PE and ERR interrupts */
|
||||
CLEAR_BIT(husart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE));
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
/* At end of Rx process, restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
}
|
||||
|
||||
#if (defined(DMA1) || defined(DMA))
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMAAbortOnError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
husart->RxXferCount = 0x00U;
|
||||
husart->TxXferCount = 0x00U;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Error Callback */
|
||||
husart->ErrorCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Error Callback */
|
||||
HAL_USART_ErrorCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
husart->hdmatx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (husart->hdmarx != NULL)
|
||||
{
|
||||
if (husart->hdmarx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
husart->TxXferCount = 0x00U;
|
||||
husart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset errorCode */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
|
||||
/* Restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Complete Callback */
|
||||
husart->AbortCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Abort Complete Callback */
|
||||
HAL_USART_AbortCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DMA USART 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 USART_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
USART_HandleTypeDef *husart = (USART_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
|
||||
|
||||
husart->hdmarx->XferAbortCallback = NULL;
|
||||
|
||||
/* Check if an Abort process is still ongoing */
|
||||
if (husart->hdmatx != NULL)
|
||||
{
|
||||
if (husart->hdmatx->XferAbortCallback != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No Abort process still ongoing : All DMA channels are aborted, call user Abort Complete callback */
|
||||
husart->TxXferCount = 0x00U;
|
||||
husart->RxXferCount = 0x00U;
|
||||
|
||||
/* Reset errorCode */
|
||||
husart->ErrorCode = HAL_USART_ERROR_NONE;
|
||||
|
||||
/* Restore husart->State to Ready */
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
/* Call user Abort complete callback */
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Abort Complete Callback */
|
||||
husart->AbortCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Abort Complete Callback */
|
||||
HAL_USART_AbortCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
}
|
||||
#endif /* DMA1 or DMA */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Simplex Send an amount of data in non-blocking mode.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
* @note The USART errors are not managed to avoid the overrun error.
|
||||
*/
|
||||
static HAL_StatusTypeDef USART_Transmit_IT(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_BUSY_TX)
|
||||
{
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) husart->pTxBuffPtr;
|
||||
husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
husart->pTxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->pTxBuffPtr += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
|
||||
}
|
||||
|
||||
if (--husart->TxXferCount == 0U)
|
||||
{
|
||||
/* Disable the USART Transmit data register empty Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
|
||||
|
||||
/* Enable the USART Transmit Complete Interrupt */
|
||||
SET_BIT(husart->Instance->CR1, USART_CR1_TCIE);
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wraps up transmission in non blocking mode.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef USART_EndTransmit_IT(USART_HandleTypeDef *husart)
|
||||
{
|
||||
/* Disable the USART Transmit Complete Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_TCIE);
|
||||
|
||||
/* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Complete Callback */
|
||||
husart->TxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Complete Callback */
|
||||
HAL_USART_TxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Simplex Receive an amount of data in non-blocking mode.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef USART_Receive_IT(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
if (husart->State == HAL_USART_STATE_BUSY_RX)
|
||||
{
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) husart->pRxBuffPtr;
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
|
||||
husart->pRxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
|
||||
husart->pRxBuffPtr += 1U;
|
||||
}
|
||||
if (--husart->RxXferCount != 0x00U)
|
||||
{
|
||||
/* Send dummy byte in order to generate the clock for the slave to send the next data */
|
||||
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x01FF);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
|
||||
}
|
||||
|
||||
if (--husart->RxXferCount != 0x00U)
|
||||
{
|
||||
/* Send dummy byte in order to generate the clock for the slave to send the next data */
|
||||
husart->Instance->DR = (DUMMY_DATA & (uint16_t)0x00FF);
|
||||
}
|
||||
}
|
||||
|
||||
if (husart->RxXferCount == 0U)
|
||||
{
|
||||
/* Disable the USART RXNE Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
|
||||
|
||||
/* Disable the USART Parity Error Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Rx Complete Callback */
|
||||
husart->RxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Rx Complete Callback */
|
||||
HAL_USART_RxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Full-Duplex Send receive an amount of data in full-duplex mode (non-blocking).
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
static HAL_StatusTypeDef USART_TransmitReceive_IT(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint16_t *tmp;
|
||||
|
||||
if (husart->State == HAL_USART_STATE_BUSY_TX_RX)
|
||||
{
|
||||
if (husart->TxXferCount != 0x00U)
|
||||
{
|
||||
if (__HAL_USART_GET_FLAG(husart, USART_FLAG_TXE) != RESET)
|
||||
{
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) husart->pTxBuffPtr;
|
||||
husart->Instance->DR = (uint16_t)(*tmp & (uint16_t)0x01FF);
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
husart->pTxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->pTxBuffPtr += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
husart->Instance->DR = (uint8_t)(*husart->pTxBuffPtr++ & (uint8_t)0x00FF);
|
||||
}
|
||||
husart->TxXferCount--;
|
||||
|
||||
/* Check the latest data transmitted */
|
||||
if (husart->TxXferCount == 0U)
|
||||
{
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_TXEIE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (husart->RxXferCount != 0x00U)
|
||||
{
|
||||
if (__HAL_USART_GET_FLAG(husart, USART_FLAG_RXNE) != RESET)
|
||||
{
|
||||
if (husart->Init.WordLength == USART_WORDLENGTH_9B)
|
||||
{
|
||||
tmp = (uint16_t *) husart->pRxBuffPtr;
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x01FF);
|
||||
husart->pRxBuffPtr += 2U;
|
||||
}
|
||||
else
|
||||
{
|
||||
*tmp = (uint16_t)(husart->Instance->DR & (uint16_t)0x00FF);
|
||||
husart->pRxBuffPtr += 1U;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (husart->Init.Parity == USART_PARITY_NONE)
|
||||
{
|
||||
*husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x00FF);
|
||||
}
|
||||
else
|
||||
{
|
||||
*husart->pRxBuffPtr++ = (uint8_t)(husart->Instance->DR & (uint8_t)0x007F);
|
||||
}
|
||||
}
|
||||
husart->RxXferCount--;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check the latest data received */
|
||||
if (husart->RxXferCount == 0U)
|
||||
{
|
||||
/* Disable the USART RXNE Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_RXNEIE);
|
||||
|
||||
/* Disable the USART Parity Error Interrupt */
|
||||
CLEAR_BIT(husart->Instance->CR1, USART_CR1_PEIE);
|
||||
|
||||
/* Disable the USART Error Interrupt: (Frame error, noise error, overrun error) */
|
||||
CLEAR_BIT(husart->Instance->CR3, USART_CR3_EIE);
|
||||
|
||||
husart->State = HAL_USART_STATE_READY;
|
||||
|
||||
#if (USE_HAL_USART_REGISTER_CALLBACKS == 1)
|
||||
/* Call registered Tx Rx Complete Callback */
|
||||
husart->TxRxCpltCallback(husart);
|
||||
#else
|
||||
/* Call legacy weak Tx Rx Complete Callback */
|
||||
HAL_USART_TxRxCpltCallback(husart);
|
||||
#endif /* USE_HAL_USART_REGISTER_CALLBACKS */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the USART peripheral.
|
||||
* @param husart Pointer to a USART_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified USART module.
|
||||
* @retval None
|
||||
*/
|
||||
static void USART_SetConfig(USART_HandleTypeDef *husart)
|
||||
{
|
||||
uint32_t tmpreg = 0x00U;
|
||||
uint32_t pclk;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_USART_INSTANCE(husart->Instance));
|
||||
assert_param(IS_USART_POLARITY(husart->Init.CLKPolarity));
|
||||
assert_param(IS_USART_PHASE(husart->Init.CLKPhase));
|
||||
assert_param(IS_USART_LASTBIT(husart->Init.CLKLastBit));
|
||||
assert_param(IS_USART_BAUDRATE(husart->Init.BaudRate));
|
||||
assert_param(IS_USART_WORD_LENGTH(husart->Init.WordLength));
|
||||
assert_param(IS_USART_STOPBITS(husart->Init.StopBits));
|
||||
assert_param(IS_USART_PARITY(husart->Init.Parity));
|
||||
assert_param(IS_USART_MODE(husart->Init.Mode));
|
||||
|
||||
/* The LBCL, CPOL and CPHA bits have to be selected when both the transmitter and the
|
||||
receiver are disabled (TE=RE=0) to ensure that the clock pulses function correctly. */
|
||||
CLEAR_BIT(husart->Instance->CR1, (USART_CR1_TE | USART_CR1_RE));
|
||||
|
||||
/*---------------------------- USART CR2 Configuration ---------------------*/
|
||||
tmpreg = husart->Instance->CR2;
|
||||
/* Clear CLKEN, CPOL, CPHA and LBCL bits */
|
||||
tmpreg &= (uint32_t)~((uint32_t)(USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_CLKEN | USART_CR2_LBCL | USART_CR2_STOP));
|
||||
/* Configure the USART Clock, CPOL, CPHA and LastBit -----------------------*/
|
||||
/* Set CPOL bit according to husart->Init.CLKPolarity value */
|
||||
/* Set CPHA bit according to husart->Init.CLKPhase value */
|
||||
/* Set LBCL bit according to husart->Init.CLKLastBit value */
|
||||
/* Set Stop Bits: Set STOP[13:12] bits according to husart->Init.StopBits value */
|
||||
tmpreg |= (uint32_t)(USART_CLOCK_ENABLE | husart->Init.CLKPolarity |
|
||||
husart->Init.CLKPhase | husart->Init.CLKLastBit | husart->Init.StopBits);
|
||||
/* Write to USART CR2 */
|
||||
WRITE_REG(husart->Instance->CR2, (uint32_t)tmpreg);
|
||||
|
||||
/*-------------------------- USART CR1 Configuration -----------------------*/
|
||||
tmpreg = husart->Instance->CR1;
|
||||
|
||||
/* Clear M, PCE, PS, TE and RE bits */
|
||||
tmpreg &= (uint32_t)~((uint32_t)(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE));
|
||||
|
||||
/* Configure the USART Word Length, Parity and mode:
|
||||
Set the M bits according to husart->Init.WordLength value
|
||||
Set PCE and PS bits according to husart->Init.Parity value
|
||||
Set TE and RE bits according to husart->Init.Mode value
|
||||
*/
|
||||
tmpreg |= (uint32_t)husart->Init.WordLength | husart->Init.Parity | husart->Init.Mode;
|
||||
|
||||
/* Write to USART CR1 */
|
||||
WRITE_REG(husart->Instance->CR1, (uint32_t)tmpreg);
|
||||
|
||||
/*-------------------------- USART CR3 Configuration -----------------------*/
|
||||
/* Clear CTSE and RTSE bits */
|
||||
CLEAR_BIT(husart->Instance->CR3, (USART_CR3_RTSE | USART_CR3_CTSE));
|
||||
|
||||
/*-------------------------- USART BRR Configuration -----------------------*/
|
||||
pclk = HAL_RCC_GetPCLK1Freq();
|
||||
husart->Instance->BRR = USART_BRR(pclk, husart->Init.BaudRate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
395
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_wwdg.c
Normal file
395
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_hal_wwdg.c
Normal file
@@ -0,0 +1,395 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_hal_wwdg.c
|
||||
* @author MCU Application Team
|
||||
* @brief WWDG HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Window Watchdog (WWDG) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral State functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### WWDG specific features #####
|
||||
==============================================================================
|
||||
[..]
|
||||
Once enabled the WWDG generates a system reset on expiry of a programmed
|
||||
time period, unless the program refreshes the counter (downcounter)
|
||||
before reaching 0x3F value (i.e. a reset is generated when the counter
|
||||
value rolls over from 0x40 to 0x3F).
|
||||
|
||||
(+) An MCU reset is also generated if the counter value is refreshed
|
||||
before the counter has reached the refresh window value. This
|
||||
implies that the counter must be refreshed in a limited window.
|
||||
(+) Once enabled the WWDG cannot be disabled except by a system reset.
|
||||
(+) WWDGRST flag in RCC_CSR register can be used to inform when a WWDG
|
||||
reset occurs.
|
||||
(+) The WWDG counter input clock is derived from the APB clock divided
|
||||
by a programmable prescaler.
|
||||
(+) WWDG clock (Hz) = PCLK1 / (4096 * Prescaler)
|
||||
(+) WWDG timeout (mS) = 1000 * Counter / WWDG clock
|
||||
(+) WWDG Counter refresh is allowed between the following limits :
|
||||
(++) min time (mS) = 1000 * (Counter _ Window) / WWDG clock
|
||||
(++) max time (mS) = 1000 * (Counter _ 0x40) / WWDG clock
|
||||
|
||||
(+) Min-max timeout value at 36 MHz(PCLK1): 910 us / 58.25 ms
|
||||
|
||||
(+) The Early Wakeup Interrupt (EWI) can be used if specific safety
|
||||
operations or data logging must be performed before the actual reset is
|
||||
generated. When the downcounter reaches the value 0x40, an EWI interrupt
|
||||
is generated and the corresponding interrupt service routine (ISR) can
|
||||
be used to trigger specific actions (such as communications or data
|
||||
logging), before resetting the device.
|
||||
In some applications, the EWI interrupt can be used to manage a software
|
||||
system check and/or system recovery/graceful degradation, without
|
||||
generating a WWDG reset. In this case, the corresponding interrupt
|
||||
service routine (ISR) should reload the WWDG counter to avoid the WWDG
|
||||
reset, then trigger the required actions.
|
||||
Note:When the EWI interrupt cannot be served, e.g. due to a system lock
|
||||
in a higher priority task, the WWDG reset will eventually be generated.
|
||||
|
||||
(+) Debug mode : When the microcontroller enters debug mode (core halted),
|
||||
the WWDG counter either continues to work normally or stops, depending
|
||||
on DBG_WWDG_STOP configuration bit in DBG module, accessible through
|
||||
__HAL_DBGMCU_FREEZE_WWDG() and __HAL_DBGMCU_UNFREEZE_WWDG() macros
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(+) Enable WWDG APB1 clock using __HAL_RCC_WWDG_CLK_ENABLE().
|
||||
|
||||
(+) Set the WWDG prescaler, refresh window, counter value and Early Wakeup
|
||||
Interrupt mode using using HAL_WWDG_Init() function.
|
||||
This enables WWDG peripheral and the downcounter starts downcounting
|
||||
from given counter value.
|
||||
Init function can be called again to modify all watchdog parameters,
|
||||
however if EWI mode has been set once, it can't be clear until next
|
||||
reset.
|
||||
|
||||
(+) The application program must refresh the WWDG counter at regular
|
||||
intervals during normal operation to prevent an MCU reset using
|
||||
HAL_WWDG_Refresh() function. This operation must occur only when
|
||||
the counter is lower than the window value already programmed.
|
||||
|
||||
(+) if Early Wakeup Interrupt mode is enable an interrupt is generated when
|
||||
the counter reaches 0x40. User can add his own code in weak function
|
||||
HAL_WWDG_EarlyWakeupCallback().
|
||||
|
||||
*** WWDG HAL driver macros list ***
|
||||
==================================
|
||||
[..]
|
||||
Below the list of most used macros in WWDG HAL driver.
|
||||
|
||||
(+) __HAL_WWDG_GET_IT_SOURCE: Check the selected WWDG's interrupt source.
|
||||
(+) __HAL_WWDG_GET_FLAG: Get the selected WWDG's flag status.
|
||||
(+) __HAL_WWDG_CLEAR_FLAG: Clear the WWDG's pending flags.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
/** @defgroup WWDG WWDG
|
||||
* @brief WWDG HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup WWDG_Exported_Functions WWDG Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup WWDG_Exported_Functions_Group1 Initialization and Configuration functions
|
||||
* @brief Initialization and Configuration functions.
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and Configuration functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Initialize and start the WWDG according to the specified parameters
|
||||
in the WWDG_InitTypeDef of associated handle.
|
||||
(+) Initialize the WWDG MSP.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the WWDG according to the specified.
|
||||
* parameters in the WWDG_InitTypeDef of associated handle.
|
||||
* @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified WWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WWDG_Init(WWDG_HandleTypeDef *hwwdg)
|
||||
{
|
||||
/* Check the WWDG handle allocation */
|
||||
if (hwwdg == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_WWDG_ALL_INSTANCE(hwwdg->Instance));
|
||||
assert_param(IS_WWDG_PRESCALER(hwwdg->Init.Prescaler));
|
||||
assert_param(IS_WWDG_WINDOW(hwwdg->Init.Window));
|
||||
assert_param(IS_WWDG_COUNTER(hwwdg->Init.Counter));
|
||||
assert_param(IS_WWDG_EWI_MODE(hwwdg->Init.EWIMode));
|
||||
|
||||
#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
|
||||
/* Reset Callback pointers */
|
||||
if(hwwdg->EwiCallback == NULL)
|
||||
{
|
||||
hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback;
|
||||
}
|
||||
|
||||
if(hwwdg->MspInitCallback == NULL)
|
||||
{
|
||||
hwwdg->MspInitCallback = HAL_WWDG_MspInit;
|
||||
}
|
||||
|
||||
/* Init the low level hardware */
|
||||
hwwdg->MspInitCallback(hwwdg);
|
||||
#else
|
||||
/* Init the low level hardware */
|
||||
HAL_WWDG_MspInit(hwwdg);
|
||||
#endif
|
||||
|
||||
/* Set WWDG Counter */
|
||||
WRITE_REG(hwwdg->Instance->CR, (WWDG_CR_WDGA | hwwdg->Init.Counter));
|
||||
/* Set WWDG Prescaler and Window */
|
||||
WRITE_REG(hwwdg->Instance->CFR, (hwwdg->Init.EWIMode | hwwdg->Init.Prescaler | hwwdg->Init.Window));
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the WWDG MSP.
|
||||
* @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified WWDG module.
|
||||
* @note When rewriting this function in user file, mechanism may be added
|
||||
* to avoid multiple initialize when HAL_WWDG_Init function is called
|
||||
* again to change parameters.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_WWDG_MspInit(WWDG_HandleTypeDef *hwwdg)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hwwdg);
|
||||
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_WWDG_MspInit could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
|
||||
/**
|
||||
* @brief Register a User WWDG Callback
|
||||
* To be used instead of the weak (surcharged) predefined callback
|
||||
* @param hwwdg WWDG handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID
|
||||
* @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID
|
||||
* @param pCallback pointer to the Callback function
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WWDG_RegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID, pWWDG_CallbackTypeDef pCallback)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
if(pCallback == NULL)
|
||||
{
|
||||
status = HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(CallbackID)
|
||||
{
|
||||
case HAL_WWDG_EWI_CB_ID:
|
||||
hwwdg->EwiCallback = pCallback;
|
||||
break;
|
||||
|
||||
case HAL_WWDG_MSPINIT_CB_ID:
|
||||
hwwdg->MspInitCallback = pCallback;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unregister a WWDG Callback
|
||||
* WWDG Callback is redirected to the weak (surcharged) predefined callback
|
||||
* @param hwwdg WWDG handle
|
||||
* @param CallbackID ID of the callback to be registered
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref HAL_WWDG_EWI_CB_ID Early WakeUp Interrupt Callback ID
|
||||
* @arg @ref HAL_WWDG_MSPINIT_CB_ID MspInit callback ID
|
||||
* @retval status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WWDG_UnRegisterCallback(WWDG_HandleTypeDef *hwwdg, HAL_WWDG_CallbackIDTypeDef CallbackID)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
switch(CallbackID)
|
||||
{
|
||||
case HAL_WWDG_EWI_CB_ID:
|
||||
hwwdg->EwiCallback = HAL_WWDG_EarlyWakeupCallback;
|
||||
break;
|
||||
|
||||
case HAL_WWDG_MSPINIT_CB_ID:
|
||||
hwwdg->MspInitCallback = HAL_WWDG_MspInit;
|
||||
break;
|
||||
|
||||
default:
|
||||
status = HAL_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup WWDG_Exported_Functions_Group2 IO operation functions
|
||||
* @brief IO operation functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### IO operation functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to:
|
||||
(+) Refresh the WWDG.
|
||||
(+) Handle WWDG interrupt request and associated function callback.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Refresh the WWDG.
|
||||
* @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified WWDG module.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_WWDG_Refresh(WWDG_HandleTypeDef *hwwdg)
|
||||
{
|
||||
/* Write to WWDG CR the WWDG Counter value to refresh with */
|
||||
WRITE_REG(hwwdg->Instance->CR, (hwwdg->Init.Counter));
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle WWDG interrupt request.
|
||||
* @note The Early Wakeup Interrupt (EWI) can be used if specific safety operations
|
||||
* or data logging must be performed before the actual reset is generated.
|
||||
* The EWI interrupt is enabled by calling HAL_WWDG_Init function with
|
||||
* EWIMode set to WWDG_EWI_ENABLE.
|
||||
* When the downcounter reaches the value 0x40, and EWI interrupt is
|
||||
* generated and the corresponding Interrupt Service Routine (ISR) can
|
||||
* be used to trigger specific actions (such as communications or data
|
||||
* logging), before resetting the device.
|
||||
* @param hwwdg pointer to a WWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified WWDG module.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_WWDG_IRQHandler(WWDG_HandleTypeDef *hwwdg)
|
||||
{
|
||||
/* Check if Early Wakeup Interrupt is enable */
|
||||
if (__HAL_WWDG_GET_IT_SOURCE(hwwdg, WWDG_IT_EWI) != RESET)
|
||||
{
|
||||
/* Check if WWDG Early Wakeup Interrupt occurred */
|
||||
if (__HAL_WWDG_GET_FLAG(hwwdg, WWDG_FLAG_EWIF) != RESET)
|
||||
{
|
||||
/* Clear the WWDG Early Wakeup flag */
|
||||
__HAL_WWDG_CLEAR_FLAG(hwwdg, WWDG_FLAG_EWIF);
|
||||
|
||||
#if (USE_HAL_WWDG_REGISTER_CALLBACKS == 1)
|
||||
/* Early Wakeup registered callback */
|
||||
hwwdg->EwiCallback(hwwdg);
|
||||
#else
|
||||
/* Early Wakeup callback */
|
||||
HAL_WWDG_EarlyWakeupCallback(hwwdg);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief WWDG Early Wakeup callback.
|
||||
* @param hwwdg : pointer to a WWDG_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified WWDG module.
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_WWDG_EarlyWakeupCallback(WWDG_HandleTypeDef *hwwdg)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hwwdg);
|
||||
|
||||
/* NOTE: This function should not be modified, when the callback is needed,
|
||||
the HAL_WWDG_EarlyWakeupCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
582
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_adc.c
Normal file
582
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_adc.c
Normal file
@@ -0,0 +1,582 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_adc.c
|
||||
* @author MCU Application Team
|
||||
* @brief ADC LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_adc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "PY32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (ADC1)
|
||||
|
||||
/** @addtogroup ADC_LL ADC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @addtogroup ADC_LL_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Definitions of ADC hardware constraints delays */
|
||||
/* Note: Only ADC IP HW delays are defined in ADC LL driver driver, */
|
||||
/* not timeout values: */
|
||||
/* Timeout values for ADC operations are dependent to device clock */
|
||||
/* configuration (system clock versus ADC clock), */
|
||||
/* and therefore must be defined in user application. */
|
||||
/* Refer to @ref ADC_LL_EC_HW_DELAYS for description of ADC timeout */
|
||||
/* values definition. */
|
||||
/* Unit: CPU cycles. */
|
||||
#define ADC_CLOCK_RATIO_VS_CPU_HIGHEST ((uint32_t) 512U * 16U * 4U)
|
||||
#define ADC_TIMEOUT_DISABLE_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1U)
|
||||
#define ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES (ADC_CLOCK_RATIO_VS_CPU_HIGHEST * 1U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup ADC_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Check of parameters for configuration of ADC hierarchical scope: */
|
||||
/* common to several ADC instances. */
|
||||
/* Check of parameters for configuration of ADC hierarchical scope: */
|
||||
/* ADC instance. */
|
||||
#define IS_LL_ADC_CLOCK(__CLOCK__) \
|
||||
( ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV64) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV32) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV16) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV8) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV4) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV2) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_SYNC_PCLK_DIV1) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV64) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV32) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV16) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV8) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV4) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV2) \
|
||||
|| ((__CLOCK__) == LL_ADC_CLOCK_ASYNC_HSI_DIV1) \
|
||||
)
|
||||
|
||||
#define IS_LL_ADC_RESOLUTION(__RESOLUTION__) \
|
||||
( ((__RESOLUTION__) == LL_ADC_RESOLUTION_12B) \
|
||||
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_10B) \
|
||||
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_8B) \
|
||||
|| ((__RESOLUTION__) == LL_ADC_RESOLUTION_6B) \
|
||||
)
|
||||
|
||||
#define IS_LL_ADC_DATA_ALIGN(__DATA_ALIGN__) \
|
||||
( ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_RIGHT) \
|
||||
|| ((__DATA_ALIGN__) == LL_ADC_DATA_ALIGN_LEFT) \
|
||||
)
|
||||
|
||||
#define IS_LL_ADC_LOW_POWER(__LOW_POWER__) \
|
||||
( ((__LOW_POWER__) == LL_ADC_LP_MODE_NONE) \
|
||||
|| ((__LOW_POWER__) == LL_ADC_LP_AUTOWAIT) \
|
||||
)
|
||||
|
||||
/* Check of parameters for configuration of ADC hierarchical scope: */
|
||||
/* ADC group regular */
|
||||
#define IS_LL_ADC_REG_TRIG_SOURCE(__REG_TRIG_SOURCE__) \
|
||||
( ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_SOFTWARE) \
|
||||
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_TRGO) \
|
||||
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM1_CH4) \
|
||||
|| ((__REG_TRIG_SOURCE__) == LL_ADC_REG_TRIG_EXT_TIM3_TRGO) \
|
||||
)
|
||||
|
||||
#define IS_LL_ADC_REG_CONTINUOUS_MODE(__REG_CONTINUOUS_MODE__) \
|
||||
( ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_SINGLE) \
|
||||
|| ((__REG_CONTINUOUS_MODE__) == LL_ADC_REG_CONV_CONTINUOUS) \
|
||||
)
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
#define IS_LL_ADC_REG_DMA_TRANSFER(__REG_DMA_TRANSFER__) \
|
||||
( ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_NONE) \
|
||||
|| ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_LIMITED) \
|
||||
|| ((__REG_DMA_TRANSFER__) == LL_ADC_REG_DMA_TRANSFER_UNLIMITED) \
|
||||
)
|
||||
#endif
|
||||
|
||||
#define IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(__REG_OVR_DATA_BEHAVIOR__) \
|
||||
( ((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_PRESERVED) \
|
||||
|| ((__REG_OVR_DATA_BEHAVIOR__) == LL_ADC_REG_OVR_DATA_OVERWRITTEN) \
|
||||
)
|
||||
|
||||
#define IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(__REG_SEQ_DISCONT_MODE__) \
|
||||
( ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_DISABLE) \
|
||||
|| ((__REG_SEQ_DISCONT_MODE__) == LL_ADC_REG_SEQ_DISCONT_1RANK) \
|
||||
)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup ADC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup ADC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize registers of all ADC instances belonging to
|
||||
* the same ADC common instance to their default reset values.
|
||||
* @note This function is performing a hard reset, using high level
|
||||
* clock source RCC ADC reset.
|
||||
* @param ADCxy_COMMON ADC common instance
|
||||
* (can be set directly from CMSIS definition or by using helper macro @ref __LL_ADC_COMMON_INSTANCE() )
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: ADC common registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_ADC_CommonDeInit(ADC_Common_TypeDef *ADCxy_COMMON)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_COMMON_INSTANCE(ADCxy_COMMON));
|
||||
|
||||
/* Force reset of ADC clock (core clock) */
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_ADC1);
|
||||
|
||||
/* Release reset of ADC clock (core clock) */
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_ADC1);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initialize registers of the selected ADC instance
|
||||
* to their default reset values.
|
||||
* @note To reset all ADC instances quickly (perform a hard reset),
|
||||
* use function @ref LL_ADC_CommonDeInit().
|
||||
* @note If this functions returns error status, it means that ADC instance
|
||||
* is in an unknown state.
|
||||
* In this case, perform a hard reset using high level
|
||||
* clock source RCC ADC reset.
|
||||
* Refer to function @ref LL_ADC_CommonDeInit().
|
||||
* @param ADCx ADC instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: ADC registers are de-initialized
|
||||
* - ERROR: ADC registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_ADC_DeInit(ADC_TypeDef *ADCx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
__IO uint32_t timeout_cpu_cycles = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
|
||||
|
||||
/* Disable ADC instance if not already disabled. */
|
||||
if(LL_ADC_IsEnabled(ADCx) == 1U)
|
||||
{
|
||||
/* Set ADC group regular trigger source to SW start to ensure to not */
|
||||
/* have an external trigger event occurring during the conversion stop */
|
||||
/* ADC disable process. */
|
||||
LL_ADC_REG_SetTriggerSource(ADCx, LL_ADC_REG_TRIG_SOFTWARE);
|
||||
|
||||
/* Stop potential ADC conversion on going on ADC group regular. */
|
||||
if(LL_ADC_REG_IsConversionOngoing(ADCx) != 0U)
|
||||
{
|
||||
if(LL_ADC_REG_IsStopConversionOngoing(ADCx) == 0U)
|
||||
{
|
||||
LL_ADC_REG_StopConversion(ADCx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(ADCx->CFGR1)|=(0x7<<6);
|
||||
(ADCx->CFGR1)|=(0x3<<10);
|
||||
__disable_irq();
|
||||
LL_ADC_REG_StartConversion(ADCx);
|
||||
LL_ADC_REG_StopConversion(ADCx);
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
/* Wait for ADC conversions are effectively stopped */
|
||||
timeout_cpu_cycles = ADC_TIMEOUT_STOP_CONVERSION_CPU_CYCLES;
|
||||
while (LL_ADC_REG_IsStopConversionOngoing(ADCx) == 1U)
|
||||
{
|
||||
if(timeout_cpu_cycles-- == 0U)
|
||||
{
|
||||
/* Time-out error */
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for ADC instance is effectively disabled */
|
||||
timeout_cpu_cycles = ADC_TIMEOUT_DISABLE_CPU_CYCLES;
|
||||
while (LL_ADC_IsEnabled(ADCx) == 1U)
|
||||
{
|
||||
if(timeout_cpu_cycles-- == 0U)
|
||||
{
|
||||
/* Time-out error */
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether ADC state is compliant with expected state */
|
||||
if(READ_BIT(ADCx->CR,(ADC_CR_ADSTP | ADC_CR_ADSTART | ADC_CR_ADEN ))== 0U)
|
||||
{
|
||||
/* ========== Reset ADC registers ========== */
|
||||
/* Reset register IER */
|
||||
CLEAR_BIT(ADCx->IER,
|
||||
( LL_ADC_IT_EOC
|
||||
| LL_ADC_IT_EOS
|
||||
| LL_ADC_IT_OVR
|
||||
| LL_ADC_IT_EOSMP
|
||||
| LL_ADC_IT_AWD )
|
||||
);
|
||||
|
||||
/* Reset register ISR */
|
||||
SET_BIT(ADCx->ISR,
|
||||
( LL_ADC_FLAG_EOC
|
||||
| LL_ADC_FLAG_EOS
|
||||
| LL_ADC_FLAG_OVR
|
||||
| LL_ADC_FLAG_EOSMP
|
||||
| LL_ADC_FLAG_AWD )
|
||||
);
|
||||
|
||||
/* Reset register CR */
|
||||
/* Bits ADC_CR_ADCAL, ADC_CR_ADSTP, ADC_CR_ADSTART are in access mode */
|
||||
/* "read-set": no direct reset applicable. */
|
||||
/* No action on register CR */
|
||||
|
||||
/* Reset register CFGR1 */
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
CLEAR_BIT(ADCx->CFGR1,
|
||||
( ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN
|
||||
| ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD
|
||||
| ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RESSEL
|
||||
| ADC_CFGR1_SCANDIR | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN )
|
||||
);
|
||||
#else
|
||||
CLEAR_BIT(ADCx->CFGR1,
|
||||
( ADC_CFGR1_AWDCH | ADC_CFGR1_AWDEN | ADC_CFGR1_AWDSGL | ADC_CFGR1_DISCEN
|
||||
| ADC_CFGR1_WAIT | ADC_CFGR1_CONT | ADC_CFGR1_OVRMOD
|
||||
| ADC_CFGR1_EXTEN | ADC_CFGR1_EXTSEL | ADC_CFGR1_ALIGN | ADC_CFGR1_RESSEL
|
||||
| ADC_CFGR1_SCANDIR )
|
||||
);
|
||||
#endif
|
||||
|
||||
/* Reset register CFGR2 */
|
||||
/* Note: Update of ADC clock mode is conditioned to ADC state disabled: */
|
||||
/* already done above. */
|
||||
CLEAR_BIT(ADCx->CFGR2, ADC_CFGR2_CKMODE);
|
||||
|
||||
/* Reset register SMPR */
|
||||
CLEAR_BIT(ADCx->SMPR, ADC_SMPR_SMP);
|
||||
|
||||
/* Reset register TR */
|
||||
MODIFY_REG(ADCx->TR, ADC_TR_HT | ADC_TR_LT, ADC_TR_HT);
|
||||
|
||||
/* Reset register CHSELR */
|
||||
|
||||
CLEAR_BIT(ADCx->CHSELR,
|
||||
( ADC_CHSELR_CHSEL12 | ADC_CHSELR_CHSEL11 | ADC_CHSELR_CHSEL9 | ADC_CHSELR_CHSEL8
|
||||
| ADC_CHSELR_CHSEL7 | ADC_CHSELR_CHSEL6 | ADC_CHSELR_CHSEL5 | ADC_CHSELR_CHSEL4
|
||||
| ADC_CHSELR_CHSEL3 | ADC_CHSELR_CHSEL2 | ADC_CHSELR_CHSEL1 | ADC_CHSELR_CHSEL0 )
|
||||
);
|
||||
|
||||
/* Reset register CCR */
|
||||
CLEAR_BIT(__LL_ADC_COMMON_INSTANCE(ADC1)->CCR,ADC_CCR_TSEN | ADC_CCR_VREFEN);
|
||||
|
||||
/* Reset register DR */
|
||||
/* bits in access mode read only, no direct reset applicable */
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* ADC instance is in an unknown state */
|
||||
/* Need to performing a hard reset of ADC instance, using high level */
|
||||
/* clock source RCC ADC reset. */
|
||||
/* Caution: On this PY32 serie, if several ADC instances are available */
|
||||
/* on the selected device, RCC ADC reset will reset */
|
||||
/* all ADC instances belonging to the common ADC instance. */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize some features of ADC instance.
|
||||
* @note These parameters have an impact on ADC scope: ADC instance.
|
||||
* Refer to corresponding unitary functions into
|
||||
* @ref ADC_LL_EF_Configuration_ADC_Instance .
|
||||
* @note The setting of these parameters by function @ref LL_ADC_Init()
|
||||
* is conditioned to ADC state:
|
||||
* ADC instance must be disabled.
|
||||
* This condition is applied to all ADC features, for efficiency
|
||||
* and compatibility over all PY32 families. However, the different
|
||||
* features can be set under different ADC state conditions
|
||||
* (setting possible with ADC enabled without conversion on going,
|
||||
* ADC enabled with conversion on going, ...)
|
||||
* Each feature can be updated afterwards with a unitary function
|
||||
* and potentially with ADC in a different state than disabled,
|
||||
* refer to description of each function for setting
|
||||
* conditioned to ADC state.
|
||||
* @note After using this function, some other features must be configured
|
||||
* using LL unitary functions.
|
||||
* The minimum configuration remaining to be done is:
|
||||
* - Set ADC group regular sequencer:
|
||||
* map channel on rank corresponding to channel number.
|
||||
* Refer to function @ref LL_ADC_REG_SetSequencerChannels();
|
||||
* - Set ADC channel sampling time
|
||||
* Refer to function LL_ADC_SetChannelSamplingTime();
|
||||
* @param ADCx ADC instance
|
||||
* @param ADC_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: ADC registers are initialized
|
||||
* - ERROR: ADC registers are not initialized
|
||||
*/
|
||||
ErrorStatus LL_ADC_Init(ADC_TypeDef *ADCx, LL_ADC_InitTypeDef *ADC_InitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
|
||||
|
||||
assert_param(IS_LL_ADC_CLOCK(ADC_InitStruct->Clock));
|
||||
assert_param(IS_LL_ADC_RESOLUTION(ADC_InitStruct->Resolution));
|
||||
assert_param(IS_LL_ADC_DATA_ALIGN(ADC_InitStruct->DataAlignment));
|
||||
assert_param(IS_LL_ADC_LOW_POWER(ADC_InitStruct->LowPowerMode));
|
||||
|
||||
/* Note: Hardware constraint (refer to description of this function): */
|
||||
/* ADC instance must be disabled. */
|
||||
if(LL_ADC_IsEnabled(ADCx) == 0U)
|
||||
{
|
||||
/* Configuration of ADC hierarchical scope: */
|
||||
/* - ADC instance */
|
||||
/* - Set ADC data resolution */
|
||||
/* - Set ADC conversion data alignment */
|
||||
/* - Set ADC low power mode */
|
||||
MODIFY_REG(ADCx->CFGR1,
|
||||
ADC_CFGR1_RESSEL
|
||||
| ADC_CFGR1_ALIGN
|
||||
| ADC_CFGR1_WAIT
|
||||
,
|
||||
ADC_InitStruct->Resolution
|
||||
| ADC_InitStruct->DataAlignment
|
||||
| ADC_InitStruct->LowPowerMode
|
||||
);
|
||||
|
||||
MODIFY_REG(ADCx->CFGR2,
|
||||
ADC_CFGR2_CKMODE
|
||||
,
|
||||
ADC_InitStruct->Clock
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialization error: ADC instance is not disabled. */
|
||||
status = ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_ADC_InitTypeDef field to default value.
|
||||
* @param ADC_InitStruct Pointer to a @ref LL_ADC_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_ADC_StructInit(LL_ADC_InitTypeDef *ADC_InitStruct)
|
||||
{
|
||||
/* Set ADC_InitStruct fields to default values */
|
||||
/* Set fields of ADC instance */
|
||||
ADC_InitStruct->Clock = LL_ADC_CLOCK_SYNC_PCLK_DIV2;
|
||||
ADC_InitStruct->Resolution = LL_ADC_RESOLUTION_12B;
|
||||
ADC_InitStruct->DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
|
||||
ADC_InitStruct->LowPowerMode = LL_ADC_LP_MODE_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize some features of ADC group regular.
|
||||
* @note These parameters have an impact on ADC scope: ADC group regular.
|
||||
* Refer to corresponding unitary functions into
|
||||
* @ref ADC_LL_EF_Configuration_ADC_Group_Regular
|
||||
* (functions with prefix "REG").
|
||||
* @note The setting of these parameters by function @ref LL_ADC_Init()
|
||||
* is conditioned to ADC state:
|
||||
* ADC instance must be disabled.
|
||||
* This condition is applied to all ADC features, for efficiency
|
||||
* and compatibility over all PY32 families. However, the different
|
||||
* features can be set under different ADC state conditions
|
||||
* (setting possible with ADC enabled without conversion on going,
|
||||
* ADC enabled with conversion on going, ...)
|
||||
* Each feature can be updated afterwards with a unitary function
|
||||
* and potentially with ADC in a different state than disabled,
|
||||
* refer to description of each function for setting
|
||||
* conditioned to ADC state.
|
||||
* @note After using this function, other features must be configured
|
||||
* using LL unitary functions.
|
||||
* The minimum configuration remaining to be done is:
|
||||
* - Set ADC group regular sequencer:
|
||||
* map channel on rank corresponding to channel number.
|
||||
* Refer to function @ref LL_ADC_REG_SetSequencerChannels();
|
||||
* - Set ADC channel sampling time
|
||||
* Refer to function LL_ADC_SetChannelSamplingTime();
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param ADCx ADC instance
|
||||
* @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: ADC registers are initialized
|
||||
* - ERROR: ADC registers are not initialized
|
||||
*/
|
||||
ErrorStatus LL_ADC_REG_Init(ADC_TypeDef *ADCx, LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_ADC_ALL_INSTANCE(ADCx));
|
||||
assert_param(IS_LL_ADC_REG_TRIG_SOURCE(ADC_REG_InitStruct->TriggerSource));
|
||||
assert_param(IS_LL_ADC_REG_SEQ_SCAN_DISCONT_MODE(ADC_REG_InitStruct->SequencerDiscont));
|
||||
assert_param(IS_LL_ADC_REG_CONTINUOUS_MODE(ADC_REG_InitStruct->ContinuousMode));
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
assert_param(IS_LL_ADC_REG_DMA_TRANSFER(ADC_REG_InitStruct->DMATransfer));
|
||||
#endif
|
||||
assert_param(IS_LL_ADC_REG_OVR_DATA_BEHAVIOR(ADC_REG_InitStruct->Overrun));
|
||||
|
||||
/* Note: Hardware constraint (refer to description of this function): */
|
||||
/* ADC instance must be disabled. */
|
||||
if(LL_ADC_IsEnabled(ADCx) == 0U)
|
||||
{
|
||||
/* Configuration of ADC hierarchical scope: */
|
||||
/* - ADC group regular */
|
||||
/* - Set ADC group regular trigger source */
|
||||
/* - Set ADC group regular sequencer discontinuous mode */
|
||||
/* - Set ADC group regular continuous mode */
|
||||
/* - Set ADC group regular conversion data transfer: no transfer or */
|
||||
/* transfer by DMA, and DMA requests mode */
|
||||
/* - Set ADC group regular overrun behavior */
|
||||
/* Note: On this PY32 serie, ADC trigger edge is set to value 0x0 by */
|
||||
/* setting of trigger source to SW start. */
|
||||
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
MODIFY_REG(ADCx->CFGR1,
|
||||
ADC_CFGR1_EXTSEL
|
||||
| ADC_CFGR1_EXTEN
|
||||
| ADC_CFGR1_DISCEN
|
||||
| ADC_CFGR1_CONT
|
||||
| ADC_CFGR1_DMAEN
|
||||
| ADC_CFGR1_DMACFG
|
||||
| ADC_CFGR1_OVRMOD
|
||||
,
|
||||
ADC_REG_InitStruct->TriggerSource
|
||||
| ADC_REG_InitStruct->SequencerDiscont
|
||||
| ADC_REG_InitStruct->ContinuousMode
|
||||
| ADC_REG_InitStruct->DMATransfer
|
||||
| ADC_REG_InitStruct->Overrun
|
||||
);
|
||||
#else
|
||||
MODIFY_REG(ADCx->CFGR1,
|
||||
ADC_CFGR1_EXTSEL
|
||||
| ADC_CFGR1_EXTEN
|
||||
| ADC_CFGR1_DISCEN
|
||||
| ADC_CFGR1_CONT
|
||||
| ADC_CFGR1_OVRMOD
|
||||
,
|
||||
ADC_REG_InitStruct->TriggerSource
|
||||
| ADC_REG_InitStruct->SequencerDiscont
|
||||
| ADC_REG_InitStruct->ContinuousMode
|
||||
| ADC_REG_InitStruct->Overrun
|
||||
);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialization error: ADC instance is not disabled. */
|
||||
status = ERROR;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value.
|
||||
* @note Depending on devices and packages, DMA may not be available.
|
||||
* Refer to device datasheet for DMA availability.
|
||||
* @param ADC_REG_InitStruct Pointer to a @ref LL_ADC_REG_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_ADC_REG_StructInit(LL_ADC_REG_InitTypeDef *ADC_REG_InitStruct)
|
||||
{
|
||||
/* Set ADC_REG_InitStruct fields to default values */
|
||||
/* Set fields of ADC group regular */
|
||||
/* Note: On this PY32 serie, ADC trigger edge is set to value 0x0 by */
|
||||
/* setting of trigger source to SW start. */
|
||||
ADC_REG_InitStruct->TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
|
||||
ADC_REG_InitStruct->SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
|
||||
ADC_REG_InitStruct->ContinuousMode = LL_ADC_REG_CONV_SINGLE;
|
||||
#if (defined(DMA) || defined(DMA1))
|
||||
ADC_REG_InitStruct->DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
|
||||
#endif
|
||||
ADC_REG_InitStruct->Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ADC1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
264
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_comp.c
Normal file
264
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_comp.c
Normal file
@@ -0,0 +1,264 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_comp.c
|
||||
* @author MCU Application Team
|
||||
* @brief COMP LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_comp.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
|
||||
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY320xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (COMP1) || defined (COMP2)
|
||||
|
||||
/** @addtogroup COMP_LL COMP
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup COMP_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Check of parameters for configuration of COMP hierarchical scope: */
|
||||
/* COMP instance. */
|
||||
|
||||
#define IS_LL_COMP_POWER_MODE(__POWER_MODE__) \
|
||||
( ((__POWER_MODE__) == LL_COMP_POWERMODE_HIGHSPEED) \
|
||||
|| ((__POWER_MODE__) == LL_COMP_POWERMODE_MEDIUMSPEED) \
|
||||
)
|
||||
|
||||
/* Note: On this PY32 series, comparator input plus parameters are */
|
||||
/* the same on all COMP instances. */
|
||||
/* However, comparator instance kept as macro parameter for */
|
||||
/* compatibility with other PY32 families. */
|
||||
#define IS_LL_COMP_INPUT_PLUS(__COMP_INSTANCE__, __INPUT_PLUS__) \
|
||||
( ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO1) \
|
||||
|| ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO2) \
|
||||
|| ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO3) \
|
||||
|| ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO4) \
|
||||
)
|
||||
|
||||
/* Note: On this PY32 series, comparator input minus parameters are */
|
||||
/* the same on all COMP instances. */
|
||||
/* However, comparator instance kept as macro parameter for */
|
||||
/* compatibility with other PY32 families. */
|
||||
#define IS_LL_COMP_INPUT_MINUS(__COMP_INSTANCE__, __INPUT_MINUS__) \
|
||||
( ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_1_4VREFINT) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_1_2VREFINT) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_3_4VREFINT) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_VREFINT) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_VCC) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_TS) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO1) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO2) \
|
||||
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO3) \
|
||||
)
|
||||
|
||||
#define IS_LL_COMP_INPUT_HYSTERESIS(__INPUT_HYSTERESIS__) \
|
||||
( ((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_DISABLE) \
|
||||
|| ((__INPUT_HYSTERESIS__) == LL_COMP_HYSTERESIS_ENABLE) \
|
||||
)
|
||||
|
||||
#define IS_LL_COMP_OUTPUT_POLARITY(__POLARITY__) \
|
||||
( ((__POLARITY__) == LL_COMP_OUTPUTPOL_NONINVERTED) \
|
||||
|| ((__POLARITY__) == LL_COMP_OUTPUTPOL_INVERTED) \
|
||||
)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup COMP_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup COMP_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize registers of the selected COMP instance
|
||||
* to their default reset values.
|
||||
* @note If comparator is locked, de-initialization by software is
|
||||
* not possible.
|
||||
* The only way to unlock the comparator is a device hardware reset.
|
||||
* @param COMPx COMP instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: COMP registers are de-initialized
|
||||
* - ERROR: COMP registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_COMP_DeInit(COMP_TypeDef *COMPx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(COMPx));
|
||||
|
||||
/* Note: Hardware constraint (refer to description of this function): */
|
||||
/* COMP instance must not be locked. */
|
||||
/* Note: If Deint the COMP1, The HYST and SCALER_EN of COMP2 will be cleared together */
|
||||
|
||||
if (LL_COMP_IsLocked(COMPx) == 0U)
|
||||
{
|
||||
LL_COMP_WriteReg(COMPx, CSR, 0x00000000U);
|
||||
LL_COMP_WriteReg(COMPx, FR, 0x00000000U);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Comparator instance is locked: de-initialization by software is */
|
||||
/* not possible. */
|
||||
/* The only way to unlock the comparator is a device hardware reset. */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize some features of COMP instance.
|
||||
* @note This function configures features of the selected COMP instance.
|
||||
* Some features are also available at scope COMP common instance
|
||||
* (common to several COMP instances).
|
||||
* Refer to functions having argument "COMPxy_COMMON" as parameter.
|
||||
* @param COMPx COMP instance
|
||||
* @param COMP_InitStruct Pointer to a @ref LL_COMP_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: COMP registers are initialized
|
||||
* - ERROR: COMP registers are not initialized
|
||||
*/
|
||||
ErrorStatus LL_COMP_Init(COMP_TypeDef *COMPx, LL_COMP_InitTypeDef *COMP_InitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_COMP_ALL_INSTANCE(COMPx));
|
||||
assert_param(IS_LL_COMP_POWER_MODE(COMP_InitStruct->PowerMode));
|
||||
assert_param(IS_LL_COMP_INPUT_PLUS(COMPx, COMP_InitStruct->InputPlus));
|
||||
assert_param(IS_LL_COMP_INPUT_MINUS(COMPx, COMP_InitStruct->InputMinus));
|
||||
assert_param(IS_LL_COMP_INPUT_HYSTERESIS(COMP_InitStruct->InputHysteresis));
|
||||
assert_param(IS_LL_COMP_OUTPUT_POLARITY(COMP_InitStruct->OutputPolarity));
|
||||
|
||||
/* Note: Hardware constraint (refer to description of this function) */
|
||||
/* COMP instance must not be locked. */
|
||||
if (LL_COMP_IsLocked(COMPx) == 0U)
|
||||
{
|
||||
/* Configuration of comparator instance : */
|
||||
/* - PowerMode */
|
||||
/* - InputPlus */
|
||||
/* - InputMinus */
|
||||
/* - OutputPolarity */
|
||||
MODIFY_REG(COMPx->CSR,
|
||||
COMP_CSR_PWRMODE
|
||||
| COMP_CSR_INPSEL
|
||||
| COMP_CSR_INMSEL
|
||||
| COMP_CSR_POLARITY
|
||||
,
|
||||
COMP_InitStruct->PowerMode
|
||||
| COMP_InitStruct->InputPlus
|
||||
| COMP_InitStruct->InputMinus
|
||||
| COMP_InitStruct->OutputPolarity
|
||||
);
|
||||
/* Set comparator hysteresis mode */
|
||||
MODIFY_REG(COMP12_COMMON->CSR_ODD, COMP_CSR_HYST,COMP_InitStruct->InputHysteresis);
|
||||
|
||||
/* Set Vrefint Scaler Enable */
|
||||
if ((COMP_InitStruct->InputMinus==LL_COMP_INPUT_MINUS_1_4VREFINT)||(COMP_InitStruct->InputMinus==LL_COMP_INPUT_MINUS_1_2VREFINT)
|
||||
||(COMP_InitStruct->InputMinus==LL_COMP_INPUT_MINUS_3_4VREFINT)||(COMP_InitStruct->InputMinus==LL_COMP_INPUT_MINUS_VREFINT))
|
||||
{
|
||||
SET_BIT(COMP12_COMMON->CSR_ODD, COMP_CSR_SCALER_EN);
|
||||
}
|
||||
if (COMP_InitStruct->DigitalFilter == 0)
|
||||
{
|
||||
/* Disable digital filter */
|
||||
CLEAR_BIT(COMPx->FR, COMP_FR_FLTEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
WRITE_REG(COMPx->FR, (COMP_FR_FLTEN | (COMP_InitStruct->DigitalFilter << COMP_FR_FLTCNT_Pos)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Initialization error: COMP instance is locked. */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_COMP_InitTypeDef field to default value.
|
||||
* @param COMP_InitStruct Pointer to a @ref LL_COMP_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_COMP_StructInit(LL_COMP_InitTypeDef *COMP_InitStruct)
|
||||
{
|
||||
/* Set COMP_InitStruct fields to default values */
|
||||
COMP_InitStruct->PowerMode = LL_COMP_POWERMODE_MEDIUMSPEED;
|
||||
COMP_InitStruct->InputPlus = LL_COMP_INPUT_PLUS_IO1;
|
||||
COMP_InitStruct->InputMinus = LL_COMP_INPUT_MINUS_VREFINT;
|
||||
COMP_InitStruct->InputHysteresis = LL_COMP_HYSTERESIS_DISABLE;
|
||||
COMP_InitStruct->OutputPolarity = LL_COMP_OUTPUTPOL_NONINVERTED;
|
||||
COMP_InitStruct->DigitalFilter = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* COMP1 || COMP2 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
111
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_crc.c
Normal file
111
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_crc.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_crc.c
|
||||
* @author MCU Application Team
|
||||
* @brief CRC LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_crc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (CRC)
|
||||
|
||||
/** @addtogroup CRC_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CRC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize CRC registers (Registers restored to their default values).
|
||||
* @param CRCx CRC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: CRC registers are de-initialized
|
||||
* - ERROR: CRC registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(CRCx));
|
||||
|
||||
if (CRCx == CRC)
|
||||
{
|
||||
|
||||
/* Reset the CRC calculation unit */
|
||||
LL_CRC_ResetCRCCalculationUnit(CRCx);
|
||||
|
||||
/* Reset IDR register */
|
||||
LL_CRC_Write_IDR(CRCx, 0x00U);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (CRC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
|
||||
265
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_dma.c
Normal file
265
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_dma.c
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_dma.c
|
||||
* @author MCU Application Team
|
||||
* @brief DMA LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_dma.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (DMA1)
|
||||
|
||||
/** @defgroup DMA_LL DMA
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup DMA_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
|
||||
((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
|
||||
((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
|
||||
|
||||
#define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
|
||||
((__VALUE__) == LL_DMA_MODE_CIRCULAR))
|
||||
|
||||
#define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
|
||||
((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
|
||||
|
||||
#define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
|
||||
((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
|
||||
|
||||
#define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \
|
||||
((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \
|
||||
((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
|
||||
|
||||
#define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \
|
||||
((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \
|
||||
((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
|
||||
|
||||
#define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
|
||||
|
||||
#define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \
|
||||
((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
|
||||
|
||||
#define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \
|
||||
(((CHANNEL) == LL_DMA_CHANNEL_1) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_2) || \
|
||||
((CHANNEL) == LL_DMA_CHANNEL_3))))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup DMA_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the DMA registers to their default reset values.
|
||||
* @param DMAx DMAx Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_DMA_CHANNEL_1
|
||||
* @arg @ref LL_DMA_CHANNEL_2
|
||||
* @arg @ref LL_DMA_CHANNEL_3
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: DMA registers are de-initialized
|
||||
* - ERROR: DMA registers are not de-initialized
|
||||
*/
|
||||
uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
|
||||
{
|
||||
DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1;
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the DMA Instance DMAx and Channel parameters*/
|
||||
assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
|
||||
|
||||
tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
|
||||
|
||||
/* Disable the selected DMAx_Channely */
|
||||
CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
|
||||
|
||||
/* Reset DMAx_Channely control register */
|
||||
LL_DMA_WriteReg(tmp, CCR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely remaining bytes register */
|
||||
LL_DMA_WriteReg(tmp, CNDTR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely peripheral address register */
|
||||
LL_DMA_WriteReg(tmp, CPAR, 0U);
|
||||
|
||||
/* Reset DMAx_Channely memory address register */
|
||||
LL_DMA_WriteReg(tmp, CMAR, 0U);
|
||||
|
||||
if (Channel == LL_DMA_CHANNEL_1)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel1 */
|
||||
LL_DMA_ClearFlag_GI1(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_2)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel2 */
|
||||
LL_DMA_ClearFlag_GI2(DMAx);
|
||||
}
|
||||
else if (Channel == LL_DMA_CHANNEL_3)
|
||||
{
|
||||
/* Reset interrupt pending bits for DMAx Channel3 */
|
||||
LL_DMA_ClearFlag_GI3(DMAx);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
|
||||
* @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
|
||||
* @arg @ref __LL_DMA_GET_INSTANCE
|
||||
* @arg @ref __LL_DMA_GET_CHANNEL
|
||||
* @param DMAx DMAx Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_DMA_CHANNEL_1
|
||||
* @arg @ref LL_DMA_CHANNEL_2
|
||||
* @arg @ref LL_DMA_CHANNEL_3
|
||||
* @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: DMA registers are initialized
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
|
||||
{
|
||||
/* Check the DMA Instance DMAx and Channel parameters*/
|
||||
assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
|
||||
|
||||
/* Check the DMA parameters from DMA_InitStruct */
|
||||
assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
|
||||
assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
|
||||
assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
|
||||
assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
|
||||
assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
|
||||
assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
|
||||
assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
|
||||
assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
|
||||
|
||||
/*---------------------------- DMAx CCR Configuration ------------------------
|
||||
* Configure DMAx_Channely: data transfer direction, data transfer mode,
|
||||
* peripheral and memory increment mode,
|
||||
* data size alignment and priority level with parameters :
|
||||
* - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
|
||||
* - Mode: DMA_CCR_CIRC bit
|
||||
* - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit
|
||||
* - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit
|
||||
* - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
|
||||
* - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
|
||||
* - Priority: DMA_CCR_PL[1:0] bits
|
||||
*/
|
||||
LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \
|
||||
DMA_InitStruct->Mode | \
|
||||
DMA_InitStruct->PeriphOrM2MSrcIncMode | \
|
||||
DMA_InitStruct->MemoryOrM2MDstIncMode | \
|
||||
DMA_InitStruct->PeriphOrM2MSrcDataSize | \
|
||||
DMA_InitStruct->MemoryOrM2MDstDataSize | \
|
||||
DMA_InitStruct->Priority);
|
||||
|
||||
/*-------------------------- DMAx CMAR Configuration -------------------------
|
||||
* Configure the memory or destination base address with parameter :
|
||||
* - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
|
||||
*/
|
||||
LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
|
||||
|
||||
/*-------------------------- DMAx CPAR Configuration -------------------------
|
||||
* Configure the peripheral or source base address with parameter :
|
||||
* - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
|
||||
*/
|
||||
LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
|
||||
|
||||
/*--------------------------- DMAx CNDTR Configuration -----------------------
|
||||
* Configure the peripheral base address with parameter :
|
||||
* - NbData: DMA_CNDTR_NDT[15:0] bits
|
||||
*/
|
||||
LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_DMA_InitTypeDef field to default value.
|
||||
* @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
|
||||
{
|
||||
/* Set DMA_InitStruct fields to default values */
|
||||
DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U;
|
||||
DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U;
|
||||
DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
|
||||
DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL;
|
||||
DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
|
||||
DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT;
|
||||
DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
|
||||
DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
|
||||
DMA_InitStruct->NbData = 0x00000000U;
|
||||
DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* DMA1 || DMA2 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
238
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_exti.c
Normal file
238
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_exti.c
Normal file
@@ -0,0 +1,238 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_exti.c
|
||||
* @author MCU Application Team
|
||||
* @brief EXTI LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_exti.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (EXTI)
|
||||
|
||||
/** @defgroup EXTI_LL EXTI
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_EXTI_LINE(__VALUE__) ((__VALUE__ == LL_EXTI_LINE_0 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_1 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_2 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_3 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_4 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_5 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_6 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_7 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_8 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_9 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_10 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_11 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_12 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_13 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_14 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_15 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_16 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_17 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_18 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_19 ) || \
|
||||
(__VALUE__ == LL_EXTI_LINE_29 ))
|
||||
|
||||
#define IS_LL_EXTI_MODE(__VALUE__) (((__VALUE__) == LL_EXTI_MODE_IT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_EVENT) \
|
||||
|| ((__VALUE__) == LL_EXTI_MODE_IT_EVENT))
|
||||
|
||||
|
||||
#define IS_LL_EXTI_TRIGGER(__VALUE__) (((__VALUE__) == LL_EXTI_TRIGGER_NONE) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_FALLING) \
|
||||
|| ((__VALUE__) == LL_EXTI_TRIGGER_RISING_FALLING))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup EXTI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup EXTI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the EXTI registers to their default reset values.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are de-initialized
|
||||
*/
|
||||
uint32_t LL_EXTI_DeInit(void)
|
||||
{
|
||||
/* Interrupt mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(IMR, 0x20080000U);
|
||||
/* Event mask register set to default reset values */
|
||||
LL_EXTI_WriteReg(EMR, 0x00000000U);
|
||||
/* Rising Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(RTSR, 0x00000000U);
|
||||
/* Falling Trigger selection register set to default reset values */
|
||||
LL_EXTI_WriteReg(FTSR, 0x00000000U);
|
||||
/* Software interrupt event register set to default reset values */
|
||||
LL_EXTI_WriteReg(SWIER, 0x00000000U);
|
||||
/* Pending register set to default reset values */
|
||||
LL_EXTI_WriteReg(PR, 0x00007FFFFU);
|
||||
|
||||
return 0x00u;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the EXTI registers according to the specified parameters in EXTI_InitStruct.
|
||||
* @param EXTI_InitStruct pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - 0x00: EXTI registers are initialized
|
||||
* - any other value : wrong configuration
|
||||
*/
|
||||
uint32_t LL_EXTI_Init(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
uint32_t status = 0x00u;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_EXTI_LINE(EXTI_InitStruct->Line));
|
||||
assert_param(IS_FUNCTIONAL_STATE(EXTI_InitStruct->LineCommand));
|
||||
assert_param(IS_LL_EXTI_MODE(EXTI_InitStruct->Mode));
|
||||
|
||||
/* ENABLE LineCommand */
|
||||
if (EXTI_InitStruct->LineCommand != DISABLE)
|
||||
{
|
||||
assert_param(IS_LL_EXTI_TRIGGER(EXTI_InitStruct->Trigger));
|
||||
|
||||
/* Configure EXTI Lines*/
|
||||
if (EXTI_InitStruct->Line != LL_EXTI_LINE_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Mode)
|
||||
{
|
||||
case LL_EXTI_MODE_IT:
|
||||
/* First Disable Event on provided Lines */
|
||||
LL_EXTI_DisableEvent(EXTI_InitStruct->Line);
|
||||
/* Then Enable IT on provided Lines */
|
||||
LL_EXTI_EnableIT(EXTI_InitStruct->Line);
|
||||
break;
|
||||
case LL_EXTI_MODE_EVENT:
|
||||
/* First Disable IT on provided Lines */
|
||||
LL_EXTI_DisableIT(EXTI_InitStruct->Line);
|
||||
/* Then Enable Event on provided Lines */
|
||||
LL_EXTI_EnableEvent(EXTI_InitStruct->Line);
|
||||
break;
|
||||
case LL_EXTI_MODE_IT_EVENT:
|
||||
/* Directly Enable IT & Event on provided Lines */
|
||||
LL_EXTI_EnableIT(EXTI_InitStruct->Line);
|
||||
LL_EXTI_EnableEvent(EXTI_InitStruct->Line);
|
||||
break;
|
||||
default:
|
||||
status = 0x01u;
|
||||
break;
|
||||
}
|
||||
if (EXTI_InitStruct->Trigger != LL_EXTI_TRIGGER_NONE)
|
||||
{
|
||||
switch (EXTI_InitStruct->Trigger)
|
||||
{
|
||||
case LL_EXTI_TRIGGER_RISING:
|
||||
/* First Disable Falling Trigger on provided Lines */
|
||||
LL_EXTI_DisableFallingTrig(EXTI_InitStruct->Line);
|
||||
/* Then Enable Rising Trigger on provided Lines */
|
||||
LL_EXTI_EnableRisingTrig(EXTI_InitStruct->Line);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_FALLING:
|
||||
/* First Disable Rising Trigger on provided Lines */
|
||||
LL_EXTI_DisableRisingTrig(EXTI_InitStruct->Line);
|
||||
/* Then Enable Falling Trigger on provided Lines */
|
||||
LL_EXTI_EnableFallingTrig(EXTI_InitStruct->Line);
|
||||
break;
|
||||
case LL_EXTI_TRIGGER_RISING_FALLING:
|
||||
LL_EXTI_EnableRisingTrig(EXTI_InitStruct->Line);
|
||||
LL_EXTI_EnableFallingTrig(EXTI_InitStruct->Line);
|
||||
break;
|
||||
default:
|
||||
status |= 0x02u;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* DISABLE LineCommand */
|
||||
else
|
||||
{
|
||||
/* De-configure EXTI Lines*/
|
||||
LL_EXTI_DisableIT(EXTI_InitStruct->Line);
|
||||
LL_EXTI_DisableEvent(EXTI_InitStruct->Line);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_EXTI_InitTypeDef field to default value.
|
||||
* @param EXTI_InitStruct Pointer to a @ref LL_EXTI_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_EXTI_StructInit(LL_EXTI_InitTypeDef *EXTI_InitStruct)
|
||||
{
|
||||
EXTI_InitStruct->Line = LL_EXTI_LINE_NONE;
|
||||
EXTI_InitStruct->LineCommand = DISABLE;
|
||||
EXTI_InitStruct->Mode = LL_EXTI_MODE_IT;
|
||||
EXTI_InitStruct->Trigger = LL_EXTI_TRIGGER_FALLING;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (EXTI) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
261
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_gpio.c
Normal file
261
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_gpio.c
Normal file
@@ -0,0 +1,261 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_gpio.c
|
||||
* @author MCU Application Team
|
||||
* @brief GPIO LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_gpio.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (GPIOA) || defined (GPIOB) || defined (GPIOF)
|
||||
|
||||
/** @addtogroup GPIO_LL
|
||||
* @{
|
||||
*/
|
||||
/** MISRA C:2012 deviation rule has been granted for following rules:
|
||||
* Rule-12.2 - Medium: RHS argument is in interval [0,INF] which is out of
|
||||
* range of the shift operator in following API :
|
||||
* LL_GPIO_Init
|
||||
* LL_GPIO_DeInit
|
||||
* LL_GPIO_SetPinMode
|
||||
* LL_GPIO_GetPinMode
|
||||
* LL_GPIO_SetPinSpeed
|
||||
* LL_GPIO_GetPinSpeed
|
||||
* LL_GPIO_SetPinPull
|
||||
* LL_GPIO_GetPinPull
|
||||
* LL_GPIO_GetAFPin_0_7
|
||||
* LL_GPIO_SetAFPin_0_7
|
||||
* LL_GPIO_SetAFPin_8_15
|
||||
* LL_GPIO_GetAFPin_8_15
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup GPIO_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_GPIO_PIN(__VALUE__) (((0x00u) < (__VALUE__)) && ((__VALUE__) <= (LL_GPIO_PIN_ALL)))
|
||||
|
||||
#define IS_LL_GPIO_MODE(__VALUE__) (((__VALUE__) == LL_GPIO_MODE_INPUT) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_OUTPUT) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_ALTERNATE) ||\
|
||||
((__VALUE__) == LL_GPIO_MODE_ANALOG))
|
||||
|
||||
#define IS_LL_GPIO_OUTPUT_TYPE(__VALUE__) (((__VALUE__) == LL_GPIO_OUTPUT_PUSHPULL) ||\
|
||||
((__VALUE__) == LL_GPIO_OUTPUT_OPENDRAIN))
|
||||
|
||||
#define IS_LL_GPIO_SPEED(__VALUE__) (((__VALUE__) == LL_GPIO_SPEED_FREQ_LOW) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_MEDIUM) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_HIGH) ||\
|
||||
((__VALUE__) == LL_GPIO_SPEED_FREQ_VERY_HIGH))
|
||||
|
||||
#define IS_LL_GPIO_PULL(__VALUE__) (((__VALUE__) == LL_GPIO_PULL_NO) ||\
|
||||
((__VALUE__) == LL_GPIO_PULL_UP) ||\
|
||||
((__VALUE__) == LL_GPIO_PULL_DOWN))
|
||||
|
||||
#define IS_LL_GPIO_ALTERNATE(__VALUE__) (((__VALUE__) == LL_GPIO_AF_0 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_1 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_2 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_3 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_4 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_5 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_6 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_7 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_8 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_9 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_10 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_11 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_12 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_13 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_14 ) ||\
|
||||
((__VALUE__) == LL_GPIO_AF_15 ))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup GPIO_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize GPIO registers (Registers restored to their default values).
|
||||
* @param GPIOx GPIO Port
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: GPIO registers are de-initialized
|
||||
* - ERROR: Wrong GPIO Port
|
||||
*/
|
||||
ErrorStatus LL_GPIO_DeInit(GPIO_TypeDef *GPIOx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
|
||||
/* Force and Release reset on clock of GPIOx Port */
|
||||
if (GPIOx == GPIOA)
|
||||
{
|
||||
LL_IOP_GRP1_ForceReset(LL_IOP_GRP1_PERIPH_GPIOA);
|
||||
LL_IOP_GRP1_ReleaseReset(LL_IOP_GRP1_PERIPH_GPIOA);
|
||||
}
|
||||
else if (GPIOx == GPIOB)
|
||||
{
|
||||
LL_IOP_GRP1_ForceReset(LL_IOP_GRP1_PERIPH_GPIOB);
|
||||
LL_IOP_GRP1_ReleaseReset(LL_IOP_GRP1_PERIPH_GPIOB);
|
||||
}
|
||||
else if (GPIOx == GPIOF)
|
||||
{
|
||||
LL_IOP_GRP1_ForceReset(LL_IOP_GRP1_PERIPH_GPIOF);
|
||||
LL_IOP_GRP1_ReleaseReset(LL_IOP_GRP1_PERIPH_GPIOF);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize GPIO registers according to the specified parameters in GPIO_InitStruct.
|
||||
* @param GPIOx GPIO Port
|
||||
* @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure
|
||||
* that contains the configuration information for the specified GPIO peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: GPIO registers are initialized according to GPIO_InitStruct content
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_GPIO_Init(GPIO_TypeDef *GPIOx, LL_GPIO_InitTypeDef *GPIO_InitStruct)
|
||||
{
|
||||
uint32_t pinpos;
|
||||
uint32_t currentpin;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
|
||||
assert_param(IS_LL_GPIO_PIN(GPIO_InitStruct->Pin));
|
||||
assert_param(IS_LL_GPIO_MODE(GPIO_InitStruct->Mode));
|
||||
assert_param(IS_LL_GPIO_PULL(GPIO_InitStruct->Pull));
|
||||
|
||||
/* ------------------------- Configure the port pins ---------------- */
|
||||
/* Initialize pinpos on first pin set */
|
||||
pinpos = 0;
|
||||
|
||||
/* Configure the port pins */
|
||||
while (((GPIO_InitStruct->Pin) >> pinpos) != 0x00u)
|
||||
{
|
||||
/* Get current io position */
|
||||
currentpin = (GPIO_InitStruct->Pin) & (0x00000001uL << pinpos);
|
||||
|
||||
if (currentpin != 0x00u)
|
||||
{
|
||||
/* Pin Mode configuration */
|
||||
LL_GPIO_SetPinMode(GPIOx, currentpin, GPIO_InitStruct->Mode);
|
||||
|
||||
if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE))
|
||||
{
|
||||
/* Check Speed mode parameters */
|
||||
assert_param(IS_LL_GPIO_SPEED(GPIO_InitStruct->Speed));
|
||||
|
||||
/* Speed mode configuration */
|
||||
LL_GPIO_SetPinSpeed(GPIOx, currentpin, GPIO_InitStruct->Speed);
|
||||
}
|
||||
|
||||
/* Pull-up Pull down resistor configuration*/
|
||||
LL_GPIO_SetPinPull(GPIOx, currentpin, GPIO_InitStruct->Pull);
|
||||
|
||||
if (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE)
|
||||
{
|
||||
/* Check Alternate parameter */
|
||||
assert_param(IS_LL_GPIO_ALTERNATE(GPIO_InitStruct->Alternate));
|
||||
|
||||
/* Speed mode configuration */
|
||||
if (currentpin < LL_GPIO_PIN_8)
|
||||
{
|
||||
LL_GPIO_SetAFPin_0_7(GPIOx, currentpin, GPIO_InitStruct->Alternate);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GPIO_SetAFPin_8_15(GPIOx, currentpin, GPIO_InitStruct->Alternate);
|
||||
}
|
||||
}
|
||||
}
|
||||
pinpos++;
|
||||
}
|
||||
|
||||
if ((GPIO_InitStruct->Mode == LL_GPIO_MODE_OUTPUT) || (GPIO_InitStruct->Mode == LL_GPIO_MODE_ALTERNATE))
|
||||
{
|
||||
/* Check Output mode parameters */
|
||||
assert_param(IS_LL_GPIO_OUTPUT_TYPE(GPIO_InitStruct->OutputType));
|
||||
|
||||
/* Output mode configuration*/
|
||||
LL_GPIO_SetPinOutputType(GPIOx, GPIO_InitStruct->Pin, GPIO_InitStruct->OutputType);
|
||||
|
||||
}
|
||||
return (SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_GPIO_InitTypeDef field to default value.
|
||||
* @param GPIO_InitStruct pointer to a @ref LL_GPIO_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LL_GPIO_StructInit(LL_GPIO_InitTypeDef *GPIO_InitStruct)
|
||||
{
|
||||
/* Reset GPIO init structure parameters values */
|
||||
GPIO_InitStruct->Pin = LL_GPIO_PIN_ALL;
|
||||
GPIO_InitStruct->Mode = LL_GPIO_MODE_ANALOG;
|
||||
GPIO_InitStruct->Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct->OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStruct->Pull = LL_GPIO_PULL_NO;
|
||||
GPIO_InitStruct->Alternate = LL_GPIO_AF_0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* defined (GPIOA) || defined (GPIOB) || defined (GPIOF) */
|
||||
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya Semiconductor *****END OF FILE****/
|
||||
194
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_i2c.c
Normal file
194
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_i2c.c
Normal file
@@ -0,0 +1,194 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_i2c.c
|
||||
* @author MCU Application Team
|
||||
* @brief I2C LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_i2c.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (I2C1) || defined (I2C2)
|
||||
|
||||
/** @defgroup I2C_LL I2C
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup I2C_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_I2C_CLOCK_SPEED(__VALUE__) (((__VALUE__) > 0U) && ((__VALUE__) <= LL_I2C_MAX_SPEED_FAST))
|
||||
|
||||
#define IS_LL_I2C_DUTY_CYCLE(__VALUE__) (((__VALUE__) == LL_I2C_DUTYCYCLE_2) || \
|
||||
((__VALUE__) == LL_I2C_DUTYCYCLE_16_9))
|
||||
|
||||
#define IS_LL_I2C_OWN_ADDRESS1(__VALUE__) ((__VALUE__) <= 0x000003FFU)
|
||||
|
||||
#define IS_LL_I2C_TYPE_ACKNOWLEDGE(__VALUE__) (((__VALUE__) == LL_I2C_ACK) || \
|
||||
((__VALUE__) == LL_I2C_NACK))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup I2C_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2C_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the I2C registers to their default reset values.
|
||||
* @param I2Cx I2C Instance.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS I2C registers are de-initialized
|
||||
* - ERROR I2C registers are not de-initialized
|
||||
*/
|
||||
uint32_t LL_I2C_DeInit(I2C_TypeDef *I2Cx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the I2C Instance I2Cx */
|
||||
assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
|
||||
|
||||
if (I2Cx == I2C1)
|
||||
{
|
||||
/* Force reset of I2C clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
|
||||
/* Release reset of I2C clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct.
|
||||
* @param I2Cx I2C Instance.
|
||||
* @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS I2C registers are initialized
|
||||
* - ERROR Not applicable
|
||||
*/
|
||||
uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct)
|
||||
{
|
||||
LL_RCC_ClocksTypeDef rcc_clocks;
|
||||
|
||||
/* Check the I2C Instance I2Cx */
|
||||
assert_param(IS_I2C_ALL_INSTANCE(I2Cx));
|
||||
|
||||
/* Check the I2C parameters from I2C_InitStruct */
|
||||
assert_param(IS_LL_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed));
|
||||
assert_param(IS_LL_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle));
|
||||
assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1));
|
||||
assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge));
|
||||
|
||||
/* Disable the selected I2Cx Peripheral */
|
||||
LL_I2C_Disable(I2Cx);
|
||||
|
||||
/* Retrieve Clock frequencies */
|
||||
LL_RCC_GetSystemClocksFreq(&rcc_clocks);
|
||||
|
||||
/*---------------------------- I2Cx SCL Clock Speed Configuration ------------
|
||||
* Configure the SCL speed :
|
||||
* - ClockSpeed: I2C_CR2_FREQ[5:0], I2C_TRISE_TRISE[5:0], I2C_CCR_FS,
|
||||
* and I2C_CCR_CCR[11:0] bits
|
||||
* - DutyCycle: I2C_CCR_DUTY[7:0] bits
|
||||
*/
|
||||
LL_I2C_ConfigSpeed(I2Cx, rcc_clocks.PCLK1_Frequency, I2C_InitStruct->ClockSpeed, I2C_InitStruct->DutyCycle);
|
||||
|
||||
/*---------------------------- I2Cx OAR1 Configuration -----------------------
|
||||
* Disable, Configure and Enable I2Cx device own address 1 with parameters :
|
||||
* - OwnAddress1: I2C_OAR1_ADD[9:8], I2C_OAR1_ADD[7:1] and I2C_OAR1_ADD0 bits
|
||||
* - OwnAddrSize: I2C_OAR1_ADDMODE bit
|
||||
*/
|
||||
LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, 0);
|
||||
|
||||
/* Enable the selected I2Cx Peripheral */
|
||||
LL_I2C_Enable(I2Cx);
|
||||
|
||||
/*---------------------------- I2Cx CR2 Configuration ------------------------
|
||||
* Configure the ACKnowledge or Non ACKnowledge condition
|
||||
* after the address receive match code or next received byte with parameter :
|
||||
* - TypeAcknowledge: I2C_CR2_NACK bit
|
||||
*/
|
||||
LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_I2C_InitTypeDef field to default value.
|
||||
* @param I2C_InitStruct Pointer to a @ref LL_I2C_InitTypeDef structure.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_I2C_StructInit(LL_I2C_InitTypeDef *I2C_InitStruct)
|
||||
{
|
||||
/* Set I2C_InitStruct fields to default values */
|
||||
I2C_InitStruct->ClockSpeed = 5000U;
|
||||
I2C_InitStruct->DutyCycle = LL_I2C_DUTYCYCLE_2;
|
||||
I2C_InitStruct->OwnAddress1 = 0U;
|
||||
I2C_InitStruct->TypeAcknowledge = LL_I2C_NACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* I2C1 || I2C2 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
158
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_led.c
Normal file
158
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_led.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_led.c
|
||||
* @author MCU Application Team
|
||||
* @brief LED LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_led.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (LED)
|
||||
|
||||
/** @addtogroup LED_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup LED_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_LED_COM_DRIVE(__VALUE__) (((__VALUE__) == LL_LED_COMDRIVE_LOW) ||\
|
||||
((__VALUE__) == LL_LED_COMDRIVE_HIGH))
|
||||
|
||||
#define IS_LL_LED_PRESCALER(__VALUE__) (((0x00u) < (__VALUE__)) && ((__VALUE__) <= (0xFFu)))
|
||||
|
||||
#define IS_LL_LED_COM_SELECT(__VALUE__) (((__VALUE__) == LL_LED_COMSELECT_1COM) ||\
|
||||
((__VALUE__) == LL_LED_COMSELECT_2COM) ||\
|
||||
((__VALUE__) == LL_LED_COMSELECT_3COM) ||\
|
||||
((__VALUE__) == LL_LED_COMSELECT_4COM))
|
||||
|
||||
#define IS_LL_LED_LIGHT_TIME(__VALUE__) (((0x01u) < (__VALUE__)) && ((__VALUE__) <= (0xFFu)))
|
||||
|
||||
#define IS_LL_LED_DEAD_TIME(__VALUE__) (((0x01u) < (__VALUE__)) && ((__VALUE__) <= (0xFFu)))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup LED_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup LED_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize LED registers.
|
||||
* @param LEDx LED Port
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: LED registers are de-initialized
|
||||
* - ERROR: Wrong LED
|
||||
*/
|
||||
ErrorStatus LL_LED_DeInit(LED_TypeDef *LEDx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LED_ALL_INSTANCE(LEDx));
|
||||
|
||||
/* Force and Release reset on clock of LEDx */
|
||||
if (LEDx == LED)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_LED);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_LED);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the LED registers according to the specified parameters in the LED_InitStruct.
|
||||
* @param LEDx LEDx Instance
|
||||
* @param LED_InitStruct pointer to a @ref LL_LED_InitTypeDef structure
|
||||
* that contains the configuration information for the specified LED peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: LED registers are initialized according to LED_InitStruct content
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_LED_Init(LED_TypeDef *LEDx, LL_LED_InitTypeDef *LED_InitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LED_ALL_INSTANCE(LEDx));
|
||||
assert_param(IS_LL_LED_COM_DRIVE(LED_InitStruct->ComDrive));
|
||||
assert_param(IS_LL_LED_PRESCALER(LED_InitStruct->Prescaler));
|
||||
assert_param(IS_LL_LED_COM_SELECT(LED_InitStruct->ComSelect));
|
||||
assert_param(IS_LL_LED_LIGHT_TIME(LED_InitStruct->LightTime));
|
||||
assert_param(IS_LL_LED_DEAD_TIME(LED_InitStruct->DeadTime));
|
||||
|
||||
/* LED Register config */
|
||||
MODIFY_REG(LEDx->CR, (uint32_t)(LED_CR_LED_COM_SEL | LED_CR_EHS),
|
||||
(LED_InitStruct->ComSelect | LED_InitStruct->ComDrive));
|
||||
LL_LED_SetPrescaler(LEDx, LED_InitStruct->Prescaler);
|
||||
LL_LED_SetLightAndDeadTime(LEDx, LED_InitStruct->LightTime, LED_InitStruct->DeadTime);
|
||||
LL_LED_Enable(LEDx);
|
||||
|
||||
return (SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_LED_InitTypeDef field to default value.
|
||||
* @param LED_InitStruct pointer to a @ref LL_LED_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LL_LED_StructInit(LL_LED_InitTypeDef *LED_InitStruct)
|
||||
{
|
||||
/* Reset LED init structure parameters values */
|
||||
LED_InitStruct->ComDrive = LL_LED_COMDRIVE_LOW;
|
||||
LED_InitStruct->Prescaler = 0x0u;
|
||||
LED_InitStruct->ComSelect = LL_LED_COMSELECT_1COM;
|
||||
LED_InitStruct->LightTime = 0x0u;
|
||||
LED_InitStruct->DeadTime = 0x0u;
|
||||
}
|
||||
|
||||
#endif /* defined (LED) */
|
||||
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya Semiconductor *****END OF FILE****/
|
||||
183
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_lptim.c
Normal file
183
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_lptim.c
Normal file
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_lptim.c
|
||||
* @author MCU Application Team
|
||||
* @brief LPTIM LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_lptim.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY32F0XX_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (LPTIM)
|
||||
|
||||
/** @addtogroup LPTIM_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup LPTIM_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_LPTIM_CLOCK_PRESCALER(__VALUE__) (((__VALUE__) == LL_LPTIM_PRESCALER_DIV1) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV2) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV4) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV8) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV16) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV32) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV64) \
|
||||
|| ((__VALUE__) == LL_LPTIM_PRESCALER_DIV128))
|
||||
|
||||
#define IS_LL_LPTIM_UPDATA_MODE(__VALUE__) (((__VALUE__) == LL_LPTIM_UPDATE_MODE_IMMEDIATE) \
|
||||
|| ((__VALUE__) == LL_LPTIM_UPDATE_MODE_ENDOFPERIOD)) \
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
/** @defgroup LPTIM_Private_Functions LPTIM Private Functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup LPTIM_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup LPTIM_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set LPTIMx registers to their reset values.
|
||||
* @param LPTIMx LP Timer instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: LPTIMx registers are de-initialized
|
||||
* - ERROR: invalid LPTIMx instance
|
||||
*/
|
||||
ErrorStatus LL_LPTIM_DeInit(LPTIM_TypeDef *LPTIMx)
|
||||
{
|
||||
ErrorStatus result = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(LPTIMx));
|
||||
|
||||
if (LPTIMx == LPTIM)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ERROR;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each fields of the LPTIM_InitStruct structure to its default
|
||||
* value.
|
||||
* @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure
|
||||
* @retval None
|
||||
*/
|
||||
void LL_LPTIM_StructInit(LL_LPTIM_InitTypeDef *LPTIM_InitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
LPTIM_InitStruct->Prescaler = LL_LPTIM_PRESCALER_DIV1;
|
||||
LPTIM_InitStruct->UpdateMode = LL_LPTIM_UPDATE_MODE_IMMEDIATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the LPTIMx peripheral according to the specified parameters.
|
||||
* @note LL_LPTIM_Init can only be called when the LPTIM instance is disabled.
|
||||
* @note LPTIMx can be disabled using unitary function @ref LL_LPTIM_Disable().
|
||||
* @param LPTIMx LP Timer Instance
|
||||
* @param LPTIM_InitStruct pointer to a @ref LL_LPTIM_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: LPTIMx instance has been initialized
|
||||
* - ERROR: LPTIMx instance hasn't been initialized
|
||||
*/
|
||||
ErrorStatus LL_LPTIM_Init(LPTIM_TypeDef *LPTIMx, LL_LPTIM_InitTypeDef *LPTIM_InitStruct)
|
||||
{
|
||||
ErrorStatus result = SUCCESS;
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LPTIM_INSTANCE(LPTIMx));
|
||||
assert_param(IS_LL_LPTIM_CLOCK_PRESCALER(LPTIM_InitStruct->Prescaler));
|
||||
assert_param(IS_LL_LPTIM_UPDATA_MODE(LPTIM_InitStruct->UpdateMode));
|
||||
/* The LPTIMx_CFGR register must only be modified when the LPTIM is disabled
|
||||
(ENABLE bit is reset to 0).
|
||||
*/
|
||||
if (LL_LPTIM_IsEnabled(LPTIMx) == 1UL)
|
||||
{
|
||||
result = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set PRESC bitfield according to Prescaler value */
|
||||
MODIFY_REG(LPTIMx->CFGR,
|
||||
(LPTIM_CFGR_PRESC | LPTIM_CFGR_PRELOAD),
|
||||
LPTIM_InitStruct->Prescaler |
|
||||
LPTIM_InitStruct->UpdateMode);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* LPTIM */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
88
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_pwr.c
Normal file
88
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_pwr.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_pwr.c
|
||||
* @author MCU Application Team
|
||||
* @brief PWR LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_pwr.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(PWR)
|
||||
|
||||
/** @defgroup PWR_LL PWR
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup PWR_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup PWR_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the PWR registers to their default reset values.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: PWR registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_PWR_DeInit(void)
|
||||
{
|
||||
/* Force reset of PWR clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_PWR);
|
||||
|
||||
/* Release reset of PWR clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_PWR);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* defined(PWR) */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
558
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_rcc.c
Normal file
558
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_rcc.c
Normal file
@@ -0,0 +1,558 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_rcc.c
|
||||
* @author MCU Application Team
|
||||
* @brief RCC LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RCC)
|
||||
|
||||
/** @addtogroup RCC_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup RCC_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_RCC_MCO_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_MCO1_CLKSOURCE))
|
||||
|
||||
#if (defined(RCC_CCIPR_COMP1SEL) && defined(RCC_CCIPR_COMP2SEL))
|
||||
#define IS_LL_RCC_COMP_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_COMP1_CLKSOURCE) \
|
||||
|| ((__VALUE__) == LL_RCC_COMP2_CLKSOURCE))
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_LPTIMSEL)
|
||||
#define IS_LL_RCC_LPTIM_CLKSOURCE(__VALUE__) (((__VALUE__) == LL_RCC_LPTIM1_CLKSOURCE))
|
||||
#endif /* LPTIM1 */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup RCC_LL_Private_Functions RCC Private functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t RCC_GetSystemClockFreq(void);
|
||||
uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency);
|
||||
uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency);
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
uint32_t RCC_PLL_GetFreqDomain_SYS(void);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup RCC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset the RCC clock configuration to the default reset state.
|
||||
* @note The default reset state of the clock configuration is given below:
|
||||
* - HSI ON and used as system clock source
|
||||
* - HSE and PLL OFF
|
||||
* - AHB and APB1 prescaler set to 1.
|
||||
* - CSS, MCO OFF
|
||||
* - All interrupts disabled
|
||||
* @note This function does not modify the configuration of the
|
||||
* - Peripheral clocks
|
||||
* - LSI, LSE and RTC clocks
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RCC registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_RCC_DeInit(void)
|
||||
{
|
||||
/* Set HSION bit and wait for HSI READY bit */
|
||||
LL_RCC_HSI_Enable();
|
||||
while (LL_RCC_HSI_IsReady() != 1U)
|
||||
{}
|
||||
|
||||
/* Set HSI_FS, HSITRIM bits to default value*/
|
||||
LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_8MHz);
|
||||
|
||||
/* Reset CFGR register */
|
||||
LL_RCC_WriteReg(CFGR, 0x00000000U);
|
||||
|
||||
/* Wait till SYSCLK is HSISYS */
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS)
|
||||
{}
|
||||
|
||||
/* Reset whole CR register but HSI in 2 steps in case HSEBYP is set */
|
||||
LL_RCC_WriteReg(CR, RCC_CR_HSION);
|
||||
while (LL_RCC_HSE_IsReady() != 0U)
|
||||
{}
|
||||
LL_RCC_WriteReg(CR, RCC_CR_HSION);
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* Wait for PLL READY bit to be reset */
|
||||
while (LL_RCC_PLL_IsReady() != 0U)
|
||||
{}
|
||||
|
||||
/* Reset PLLCFGR register */
|
||||
LL_RCC_WriteReg(PLLCFGR, 0x00000000U);
|
||||
#endif
|
||||
/* Disable all interrupts */
|
||||
LL_RCC_WriteReg(CIER, 0x00000000U);
|
||||
|
||||
/* Clear all interrupts flags */
|
||||
LL_RCC_WriteReg(CICR, 0xFFFFFFFFU);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_EF_Get_Freq
|
||||
* @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
|
||||
* and different peripheral clocks available on the device.
|
||||
* @note If SYSCLK source is HSI, function returns values based on HSI_VALUE divided by HSI division factor(**)
|
||||
* @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(***)
|
||||
* @note If SYSCLK source is PLL, function returns values based on HSE_VALUE(***)
|
||||
* or HSI_VALUE(**) multiplied/divided by the PLL factors.
|
||||
* @note (**) HSI_VALUE is a constant defined in this file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
* @note (***) HSE_VALUE is a constant defined in this file (default value
|
||||
* 8 MHz), user has to ensure that HSE_VALUE is same as the real
|
||||
* frequency of the crystal used. Otherwise, this function may
|
||||
* have wrong result.
|
||||
* @note The result of this function could be incorrect when using fractional
|
||||
* value for HSE crystal.
|
||||
* @note This function can be used by the user application to compute the
|
||||
* baud-rate for the communication peripherals or configure other parameters.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the frequencies of different on chip clocks; System, AHB and APB1 buses clocks
|
||||
* @note Each time SYSCLK, HCLK and/or PCLK1 clock changes, this function
|
||||
* must be called to update structure fields. Otherwise, any
|
||||
* configuration based on this function will be incorrect.
|
||||
* @param RCC_Clocks pointer to a @ref LL_RCC_ClocksTypeDef structure which will hold the clocks frequencies
|
||||
* @retval None
|
||||
*/
|
||||
void LL_RCC_GetSystemClocksFreq(LL_RCC_ClocksTypeDef *RCC_Clocks)
|
||||
{
|
||||
/* Get SYSCLK frequency */
|
||||
RCC_Clocks->SYSCLK_Frequency = RCC_GetSystemClockFreq();
|
||||
|
||||
/* HCLK clock frequency */
|
||||
RCC_Clocks->HCLK_Frequency = RCC_GetHCLKClockFreq(RCC_Clocks->SYSCLK_Frequency);
|
||||
|
||||
/* PCLK1 clock frequency */
|
||||
RCC_Clocks->PCLK1_Frequency = RCC_GetPCLK1ClockFreq(RCC_Clocks->HCLK_Frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return MCO clock frequency
|
||||
* @param MCOx This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_MCO1_CLKSOURCE
|
||||
* @retval MCO clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (HSE, LSI or LSE) is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetMCOClockFreq(uint32_t MCOx)
|
||||
{
|
||||
uint32_t mco_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_MCO_CLKSOURCE(MCOx));
|
||||
|
||||
switch (LL_RCC_GetMCOClockSource(MCOx))
|
||||
{
|
||||
case LL_RCC_MCO1SOURCE_SYSCLK: /* MCO Clock is SYSCLK */
|
||||
mco_frequency = SystemCoreClock;
|
||||
break;
|
||||
case LL_RCC_MCO1SOURCE_HSI: /* MCO Clock is HSI */
|
||||
mco_frequency = LL_RCC_HSI_GetFreq();
|
||||
break;
|
||||
case LL_RCC_MCO1SOURCE_HSE: /* MCO Clock is HSE */
|
||||
if (LL_RCC_HSE_IsReady() == 1U)
|
||||
{
|
||||
mco_frequency = HSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
case LL_RCC_MCO1SOURCE_PLLCLK: /* MCO Clock is PLLCLK */
|
||||
mco_frequency = RCC_PLL_GetFreqDomain_SYS();
|
||||
break;
|
||||
#endif
|
||||
case LL_RCC_MCO1SOURCE_LSI: /* MCO Clock is LSI */
|
||||
if (LL_RCC_LSI_IsReady() == 1U)
|
||||
{
|
||||
mco_frequency = LSI_VALUE;
|
||||
}
|
||||
break;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case LL_RCC_MCO1SOURCE_LSE: /* MCO Clock is LSE */
|
||||
if (LL_RCC_LSE_IsReady() == 1U)
|
||||
{
|
||||
mco_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case LL_RCC_MCO1SOURCE_NOCLOCK: /* No clock used as MCO clock source */
|
||||
default:
|
||||
mco_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
return mco_frequency;
|
||||
}
|
||||
|
||||
mco_frequency = mco_frequency / (1U << (LL_RCC_GetMCODiv(MCOx) >> RCC_CFGR_MCOPRE_Pos));
|
||||
|
||||
return mco_frequency;
|
||||
}
|
||||
|
||||
#if defined(RCC_BDCR_LSCOEN)
|
||||
/**
|
||||
* @brief Return LSC clock frequency
|
||||
* @retval LSC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (LSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetLSCClockFreq(void)
|
||||
{
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
uint32_t lsc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
switch (LL_RCC_LSCO_GetSource())
|
||||
{
|
||||
case LL_RCC_LSCO_CLKSOURCE_LSE: /* LSC Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() == 1U)
|
||||
{
|
||||
lsc_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LSCO_CLKSOURCE_LSI: /* LSC Clock is LSI Osc. */
|
||||
default:
|
||||
if (LL_RCC_LSI_IsReady() == 1U)
|
||||
{
|
||||
lsc_frequency = LSI_VALUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return lsc_frequency;
|
||||
#else
|
||||
return LSI_VALUE;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RCC_CCIPR_PVDSEL)
|
||||
/**
|
||||
* @brief Return PVD clock frequency
|
||||
* @retval PVD clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (PCLK1, LSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetPVDClockFreq(void)
|
||||
{
|
||||
uint32_t pvd_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* PVDCLK clock frequency */
|
||||
switch (LL_RCC_GetPVDClockSource())
|
||||
{
|
||||
case LL_RCC_PVD_CLKSOURCE_LSC: /* PVD Clock is LSC */
|
||||
pvd_frequency = LL_RCC_GetLSCClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_PVD_CLKSOURCE_PCLK1: /* PVD Clock is PCLK1 */
|
||||
default:
|
||||
pvd_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
}
|
||||
return pvd_frequency;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(COMP1)
|
||||
/**
|
||||
* @brief Return COMP clock frequency
|
||||
* @param COMPx This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_COMP1_CLKSOURCE
|
||||
* @retval COMP clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (PCLK1, LSI or LSE) is not ready
|
||||
*/
|
||||
uint32_t LL_RCC_GetCOMPClockFreq(uint32_t COMPx)
|
||||
{
|
||||
uint32_t comp_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_COMP_CLKSOURCE(COMPx));
|
||||
|
||||
if (COMPx == LL_RCC_COMP1_CLKSOURCE)
|
||||
{
|
||||
/* COMP1CLK clock frequency */
|
||||
switch (LL_RCC_GetCOMPClockSource(COMPx))
|
||||
{
|
||||
case LL_RCC_COMP1_CLKSOURCE_LSC: /* COMP1 Clock is LSC */
|
||||
comp_frequency = LL_RCC_GetLSCClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_COMP1_CLKSOURCE_PCLK1: /* COMP1 Clock is PCLK1 */
|
||||
default:
|
||||
comp_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(COMP2)
|
||||
else
|
||||
{
|
||||
/* COMP2CLK clock frequency */
|
||||
switch (LL_RCC_GetCOMPClockSource(COMPx))
|
||||
{
|
||||
case LL_RCC_COMP2_CLKSOURCE_LSC: /* COMP2 Clock is LSC */
|
||||
comp_frequency = LL_RCC_GetLSCClockFreq();
|
||||
break;
|
||||
|
||||
case LL_RCC_COMP2_CLKSOURCE_PCLK1: /* COMP2 Clock is PCLK1 */
|
||||
default:
|
||||
comp_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return comp_frequency;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Return LPTIMx clock frequency
|
||||
* @param LPTIMx This parameter can be one of the following values:
|
||||
* @arg @ref LL_RCC_LPTIM1_CLKSOURCE
|
||||
* @retval LPTIM clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillator (PCLK1, LSI or LSE) is not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetLPTIMClockFreq(uint32_t LPTIMx)
|
||||
{
|
||||
uint32_t lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* Check parameter */
|
||||
assert_param(IS_LL_RCC_LPTIM_CLKSOURCE(LPTIMx));
|
||||
|
||||
if (LPTIMx == LL_RCC_LPTIM1_CLKSOURCE)
|
||||
{
|
||||
/* LPTIM1CLK clock frequency */
|
||||
switch (LL_RCC_GetLPTIMClockSource(LPTIMx))
|
||||
{
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_LSI: /* LPTIM1 Clock is LSI Osc. */
|
||||
if (LL_RCC_LSI_IsReady() == 1U)
|
||||
{
|
||||
lptim_frequency = LSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_NONE: /* No clock used as LPTIM1 clock source */
|
||||
lptim_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_LSE: /* LPTIM1 Clock is LSE Osc. */
|
||||
if (LL_RCC_LSE_IsReady() == 1U)
|
||||
{
|
||||
lptim_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case LL_RCC_LPTIM1_CLKSOURCE_PCLK1: /* LPTIM1 Clock is PCLK1 */
|
||||
default:
|
||||
lptim_frequency = RCC_GetPCLK1ClockFreq(RCC_GetHCLKClockFreq(RCC_GetSystemClockFreq()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lptim_frequency;
|
||||
}
|
||||
|
||||
#if defined(RCC_BDCR_RTCSEL)
|
||||
/**
|
||||
* @brief Return RTC clock frequency
|
||||
* @retval RTC clock frequency (in Hz)
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NO indicates that oscillators (LSI, LSE or HSE) are not ready
|
||||
* - @ref LL_RCC_PERIPH_FREQUENCY_NA indicates that no clock source selected
|
||||
*/
|
||||
uint32_t LL_RCC_GetRTCClockFreq(void)
|
||||
{
|
||||
uint32_t rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
|
||||
/* RTCCLK clock frequency */
|
||||
switch (LL_RCC_GetRTCClockSource())
|
||||
{
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case LL_RCC_RTC_CLKSOURCE_LSE: /* LSE clock used as RTC clock source */
|
||||
if (LL_RCC_LSE_IsReady() == 1U)
|
||||
{
|
||||
rtc_frequency = LSE_VALUE;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case LL_RCC_RTC_CLKSOURCE_LSI: /* LSI clock used as RTC clock source */
|
||||
if (LL_RCC_LSI_IsReady() == 1U)
|
||||
{
|
||||
rtc_frequency = LSI_VALUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LL_RCC_RTC_CLKSOURCE_HSE_DIV128: /* HSE/128 clock used as RTC clock source */
|
||||
if (LL_RCC_HSE_IsReady() == 1U)
|
||||
{
|
||||
rtc_frequency = HSE_VALUE / 128U;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case LL_RCC_RTC_CLKSOURCE_NONE: /* No clock used as RTC clock source */
|
||||
default:
|
||||
rtc_frequency = LL_RCC_PERIPH_FREQUENCY_NA;
|
||||
break;
|
||||
}
|
||||
return rtc_frequency;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup RCC_LL_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return SYSTEM clock frequency
|
||||
* @retval SYSTEM clock frequency (in Hz)
|
||||
*/
|
||||
uint32_t RCC_GetSystemClockFreq(void)
|
||||
{
|
||||
uint32_t frequency;
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
switch (LL_RCC_GetSysClkSource())
|
||||
{
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_HSE: /* HSE used as system clock source */
|
||||
frequency = HSE_VALUE;
|
||||
break;
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_PLL: /* PLL used as system clock source */
|
||||
frequency = RCC_PLL_GetFreqDomain_SYS();
|
||||
break;
|
||||
#endif
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_LSI:
|
||||
frequency = LSI_VALUE;
|
||||
#if defined(RCC_LSE_SUPPORT)
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_LSE:
|
||||
frequency = LSE_VALUE;
|
||||
#endif
|
||||
case LL_RCC_SYS_CLKSOURCE_STATUS_HSISYS: /* HSISYS used as system clock source */
|
||||
default:
|
||||
frequency = __LL_RCC_CALC_HSI_FREQ(LL_RCC_GetHSIDiv());
|
||||
break;
|
||||
}
|
||||
|
||||
return frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return HCLK clock frequency
|
||||
* @param SYSCLK_Frequency SYSCLK clock frequency
|
||||
* @retval HCLK clock frequency (in Hz)
|
||||
*/
|
||||
uint32_t RCC_GetHCLKClockFreq(uint32_t SYSCLK_Frequency)
|
||||
{
|
||||
/* HCLK clock frequency */
|
||||
return __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, LL_RCC_GetAHBPrescaler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return PCLK1 clock frequency
|
||||
* @param HCLK_Frequency HCLK clock frequency
|
||||
* @retval PCLK1 clock frequency (in Hz)
|
||||
*/
|
||||
uint32_t RCC_GetPCLK1ClockFreq(uint32_t HCLK_Frequency)
|
||||
{
|
||||
/* PCLK1 clock frequency */
|
||||
return __LL_RCC_CALC_PCLK1_FREQ(HCLK_Frequency, LL_RCC_GetAPB1Prescaler());
|
||||
}
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/**
|
||||
* @brief Return PLL clock frequency used for system domain
|
||||
* @retval PLL clock frequency (in Hz)
|
||||
*/
|
||||
uint32_t RCC_PLL_GetFreqDomain_SYS(void)
|
||||
{
|
||||
uint32_t pllinputfreq;
|
||||
uint32_t pllsource;
|
||||
|
||||
pllsource = LL_RCC_PLL_GetMainSource();
|
||||
|
||||
switch (pllsource)
|
||||
{
|
||||
case LL_RCC_PLLSOURCE_HSE: /* HSE used as PLL clock source */
|
||||
pllinputfreq = HSE_VALUE;
|
||||
break;
|
||||
|
||||
case LL_RCC_PLLSOURCE_HSI: /* HSI used as PLL clock source */
|
||||
default:
|
||||
pllinputfreq = LL_RCC_HSI_GetFreq();
|
||||
break;
|
||||
}
|
||||
return __LL_RCC_CALC_PLLCLK_FREQ(pllinputfreq);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* defined(RCC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya*****END OF FILE****/
|
||||
550
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_rtc.c
Normal file
550
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_rtc.c
Normal file
@@ -0,0 +1,550 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_rtc.c
|
||||
* @author MCU Application Team
|
||||
* @brief RTC LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_rtc.h"
|
||||
#include "py32f0xx_ll_cortex.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(RTC)
|
||||
|
||||
/** @addtogroup RTC_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @addtogroup RTC_LL_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
/* Default values used for prescaler */
|
||||
#define RTC_ASYNCH_PRESC_DEFAULT 0x00007FFFU
|
||||
|
||||
/* Values used for timeout */
|
||||
#define RTC_INITMODE_TIMEOUT 2000U /* 2s when tick set to 1ms */
|
||||
#define RTC_SYNCHRO_TIMEOUT 2000U /* 2s when tick set to 1ms */
|
||||
#define RTC_WAIT_RTOFF_ZERO 4U /* 1ms when tick set to 1ms */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup RTC_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_RTC_ASYNCH_PREDIV(__VALUE__) ((__VALUE__) <= 0xFFFFFU)
|
||||
|
||||
#define IS_LL_RTC_FORMAT(__VALUE__) (((__VALUE__) == LL_RTC_FORMAT_BIN) \
|
||||
|| ((__VALUE__) == LL_RTC_FORMAT_BCD))
|
||||
|
||||
#define IS_LL_RTC_HOUR24(__HOUR__) ((__HOUR__) <= 23U)
|
||||
#define IS_LL_RTC_MINUTES(__MINUTES__) ((__MINUTES__) <= 59U)
|
||||
#define IS_LL_RTC_SECONDS(__SECONDS__) ((__SECONDS__) <= 59U)
|
||||
#define IS_LL_RTC_CALIB_OUTPUT(__OUTPUT__) (((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_NONE) || \
|
||||
((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_RTCCLOCK) || \
|
||||
((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_ALARM) || \
|
||||
((__OUTPUT__) == LL_RTC_CALIB_OUTPUT_SECOND))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup RTC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup RTC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-Initializes the RTC registers to their default reset values.
|
||||
* @note This function doesn't reset the RTC Clock source and RTC Backup Data
|
||||
* registers.
|
||||
* @param RTCx RTC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC registers are de-initialized
|
||||
* - ERROR: RTC registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_RTC_DeInit(RTC_TypeDef *RTCx)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Disable the write protection for RTC registers */
|
||||
LL_RTC_DisableWriteProtection(RTCx);
|
||||
|
||||
/* Set Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
LL_RTC_WriteReg(RTCx, CNTL, 0x0000);
|
||||
LL_RTC_WriteReg(RTCx, CNTH, 0x0000);
|
||||
LL_RTC_WriteReg(RTCx, PRLH, 0x0000);
|
||||
LL_RTC_WriteReg(RTCx, PRLL, 0x8000);
|
||||
LL_RTC_WriteReg(RTCx, CRH, 0x0000);
|
||||
LL_RTC_WriteReg(RTCx, CRL, 0x0020);
|
||||
|
||||
/* Reset Tamper and alternate functions configuration register */
|
||||
LL_RTC_WriteReg(RTCx, BKP_RTCCR, 0x0000);
|
||||
|
||||
/* Exit Initialization Mode */
|
||||
if (LL_RTC_ExitInitMode(RTCx) != ERROR)
|
||||
{
|
||||
/* Wait till the RTC RSF flag is set */
|
||||
status = LL_RTC_WaitForSynchro(RTCx);
|
||||
|
||||
/* Clear RSF Flag */
|
||||
LL_RTC_ClearFlag_RS(RTCx);
|
||||
|
||||
/* Enable the write protection for RTC registers */
|
||||
LL_RTC_EnableWriteProtection(RTCx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Enable the write protection for RTC registers */
|
||||
LL_RTC_EnableWriteProtection(RTCx);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the RTC registers according to the specified parameters
|
||||
* in RTC_InitStruct.
|
||||
* @param RTCx RTC Instance
|
||||
* @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure that contains
|
||||
* the configuration information for the RTC peripheral.
|
||||
* @note The RTC Prescaler register is write protected and can be written in
|
||||
* initialization mode only.
|
||||
* @note the user should call LL_RTC_StructInit() or the structure of Prescaler
|
||||
* need to be initialized before RTC init()
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC registers are initialized
|
||||
* - ERROR: RTC registers are not initialized
|
||||
*/
|
||||
ErrorStatus LL_RTC_Init(RTC_TypeDef *RTCx, LL_RTC_InitTypeDef *RTC_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
assert_param(IS_LL_RTC_ASYNCH_PREDIV(RTC_InitStruct->AsynchPrescaler));
|
||||
assert_param(IS_LL_RTC_CALIB_OUTPUT(RTC_InitStruct->OutPutSource));
|
||||
/* Waiting for synchro */
|
||||
if (LL_RTC_WaitForSynchro(RTCx) != ERROR)
|
||||
{
|
||||
/* Set Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
/* Clear Flag Bits */
|
||||
LL_RTC_ClearFlag_ALR(RTCx);
|
||||
LL_RTC_ClearFlag_OW(RTCx);
|
||||
LL_RTC_ClearFlag_SEC(RTCx);
|
||||
|
||||
/* Set the signal which will be routed to RTC Tamper Pin */
|
||||
LL_RTC_SetOutputSource(RTCx, RTC_InitStruct->OutPutSource);
|
||||
|
||||
/* Configure Synchronous and Asynchronous prescaler factor */
|
||||
LL_RTC_SetAsynchPrescaler(RTCx, RTC_InitStruct->AsynchPrescaler);
|
||||
|
||||
/* Exit Initialization Mode */
|
||||
LL_RTC_ExitInitMode(RTCx);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_RTC_InitTypeDef field to default value.
|
||||
* @param RTC_InitStruct pointer to a @ref LL_RTC_InitTypeDef structure which will be initialized.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_RTC_StructInit(LL_RTC_InitTypeDef *RTC_InitStruct)
|
||||
{
|
||||
/* Set RTC_InitStruct fields to default values */
|
||||
RTC_InitStruct->AsynchPrescaler = RTC_ASYNCH_PRESC_DEFAULT;
|
||||
RTC_InitStruct->OutPutSource = LL_RTC_CALIB_OUTPUT_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the RTC current time.
|
||||
* @param RTCx RTC Instance
|
||||
* @param RTC_Format This parameter can be one of the following values:
|
||||
* @arg @ref LL_RTC_FORMAT_BIN
|
||||
* @arg @ref LL_RTC_FORMAT_BCD
|
||||
* @param RTC_TimeStruct pointer to a RTC_TimeTypeDef structure that contains
|
||||
* the time configuration information for the RTC.
|
||||
* @note The user should call LL_RTC_TIME_StructInit() or the structure
|
||||
* of time need to be initialized before time init()
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC Time register is configured
|
||||
* - ERROR: RTC Time register is not configured
|
||||
*/
|
||||
ErrorStatus LL_RTC_TIME_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_TimeTypeDef *RTC_TimeStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
uint32_t counter_time = 0U;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
assert_param(IS_LL_RTC_FORMAT(RTC_Format));
|
||||
|
||||
if (RTC_Format == LL_RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_LL_RTC_HOUR24(RTC_TimeStruct->Hours));
|
||||
assert_param(IS_LL_RTC_MINUTES(RTC_TimeStruct->Minutes));
|
||||
assert_param(IS_LL_RTC_SECONDS(RTC_TimeStruct->Seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)));
|
||||
assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)));
|
||||
assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds)));
|
||||
}
|
||||
|
||||
/* Enter Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
/* Check the input parameters format */
|
||||
if (RTC_Format == LL_RTC_FORMAT_BIN)
|
||||
{
|
||||
counter_time = (uint32_t)(((uint32_t)RTC_TimeStruct->Hours * 3600U) + \
|
||||
((uint32_t)RTC_TimeStruct->Minutes * 60U) + \
|
||||
((uint32_t)RTC_TimeStruct->Seconds));
|
||||
LL_RTC_TIME_Set(RTCx, counter_time);
|
||||
}
|
||||
else
|
||||
{
|
||||
counter_time = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Hours)) * 3600U) + \
|
||||
((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Minutes)) * 60U) + \
|
||||
((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_TimeStruct->Seconds))));
|
||||
LL_RTC_TIME_Set(RTCx, counter_time);
|
||||
}
|
||||
status = SUCCESS;
|
||||
}
|
||||
/* Exit Initialization mode */
|
||||
LL_RTC_ExitInitMode(RTCx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_RTC_TimeTypeDef field to default value (Time = 00h:00min:00sec).
|
||||
* @param RTC_TimeStruct pointer to a @ref LL_RTC_TimeTypeDef structure which will be initialized.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_RTC_TIME_StructInit(LL_RTC_TimeTypeDef *RTC_TimeStruct)
|
||||
{
|
||||
/* Time = 00h:00min:00sec */
|
||||
RTC_TimeStruct->Hours = 0U;
|
||||
RTC_TimeStruct->Minutes = 0U;
|
||||
RTC_TimeStruct->Seconds = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the RTC Alarm.
|
||||
* @param RTCx RTC Instance
|
||||
* @param RTC_Format This parameter can be one of the following values:
|
||||
* @arg @ref LL_RTC_FORMAT_BIN
|
||||
* @arg @ref LL_RTC_FORMAT_BCD
|
||||
* @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure that
|
||||
* contains the alarm configuration parameters.
|
||||
* @note the user should call LL_RTC_ALARM_StructInit() or the structure
|
||||
* of Alarm need to be initialized before Alarm init()
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: ALARM registers are configured
|
||||
* - ERROR: ALARM registers are not configured
|
||||
*/
|
||||
ErrorStatus LL_RTC_ALARM_Init(RTC_TypeDef *RTCx, uint32_t RTC_Format, LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
uint32_t counter_alarm = 0U;
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
assert_param(IS_LL_RTC_FORMAT(RTC_Format));
|
||||
|
||||
if (RTC_Format == LL_RTC_FORMAT_BIN)
|
||||
{
|
||||
assert_param(IS_LL_RTC_HOUR24(RTC_AlarmStruct->AlarmTime.Hours));
|
||||
assert_param(IS_LL_RTC_MINUTES(RTC_AlarmStruct->AlarmTime.Minutes));
|
||||
assert_param(IS_LL_RTC_SECONDS(RTC_AlarmStruct->AlarmTime.Seconds));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert_param(IS_LL_RTC_HOUR24(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)));
|
||||
assert_param(IS_LL_RTC_MINUTES(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)));
|
||||
assert_param(IS_LL_RTC_SECONDS(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds)));
|
||||
}
|
||||
|
||||
/* Enter Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
/* Check the input parameters format */
|
||||
if (RTC_Format == LL_RTC_FORMAT_BIN)
|
||||
{
|
||||
counter_alarm = (uint32_t)(((uint32_t)RTC_AlarmStruct->AlarmTime.Hours * 3600U) + \
|
||||
((uint32_t)RTC_AlarmStruct->AlarmTime.Minutes * 60U) + \
|
||||
((uint32_t)RTC_AlarmStruct->AlarmTime.Seconds));
|
||||
LL_RTC_ALARM_Set(RTCx, counter_alarm);
|
||||
}
|
||||
else
|
||||
{
|
||||
counter_alarm = (((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Hours)) * 3600U) + \
|
||||
((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Minutes)) * 60U) + \
|
||||
((uint32_t)(__LL_RTC_CONVERT_BCD2BIN(RTC_AlarmStruct->AlarmTime.Seconds))));
|
||||
LL_RTC_ALARM_Set(RTCx, counter_alarm);
|
||||
}
|
||||
status = SUCCESS;
|
||||
}
|
||||
/* Exit Initialization mode */
|
||||
LL_RTC_ExitInitMode(RTCx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_RTC_AlarmTypeDef of ALARM field to default value (Time = 00h:00mn:00sec /
|
||||
* Day = 1st day of the month/Mask = all fields are masked).
|
||||
* @param RTC_AlarmStruct pointer to a @ref LL_RTC_AlarmTypeDef structure which will be initialized.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_RTC_ALARM_StructInit(LL_RTC_AlarmTypeDef *RTC_AlarmStruct)
|
||||
{
|
||||
/* Alarm Time Settings : Time = 00h:00mn:00sec */
|
||||
RTC_AlarmStruct->AlarmTime.Hours = 0U;
|
||||
RTC_AlarmStruct->AlarmTime.Minutes = 0U;
|
||||
RTC_AlarmStruct->AlarmTime.Seconds = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters the RTC Initialization mode.
|
||||
* @param RTCx RTC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC is in Init mode
|
||||
* - ERROR: RTC is not in Init mode
|
||||
*/
|
||||
ErrorStatus LL_RTC_EnterInitMode(RTC_TypeDef *RTCx)
|
||||
{
|
||||
__IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Wait till RTC is in INIT state and if Time out is reached exit */
|
||||
tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
|
||||
while ((timeout != 0U) && (tmp == 0U))
|
||||
{
|
||||
if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
|
||||
{
|
||||
timeout --;
|
||||
}
|
||||
tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
|
||||
if (timeout == 0U)
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the write protection for RTC registers */
|
||||
LL_RTC_DisableWriteProtection(RTCx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exit the RTC Initialization mode.
|
||||
* @note When the initialization sequence is complete, the calendar restarts
|
||||
* counting after 4 RTCCLK cycles.
|
||||
* @param RTCx RTC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC exited from in Init mode
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_RTC_ExitInitMode(RTC_TypeDef *RTCx)
|
||||
{
|
||||
__IO uint32_t timeout = RTC_INITMODE_TIMEOUT;
|
||||
__IO uint32_t timeout_waitRtoffZer0 = RTC_WAIT_RTOFF_ZERO;
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Disable initialization mode */
|
||||
LL_RTC_EnableWriteProtection(RTCx);
|
||||
|
||||
/* Wait till RTC is in INIT state and if Time out is reached exit */
|
||||
tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
|
||||
while ((timeout_waitRtoffZer0 != 0U) && (tmp !=0U))
|
||||
{
|
||||
if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
|
||||
{
|
||||
timeout_waitRtoffZer0 --;
|
||||
}
|
||||
tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
|
||||
}
|
||||
while ((timeout != 0U) && (tmp ==0U))
|
||||
{
|
||||
if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
|
||||
{
|
||||
timeout --;
|
||||
}
|
||||
tmp = LL_RTC_IsActiveFlag_RTOF(RTCx);
|
||||
if (timeout == 0U)
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the Time Counter
|
||||
* @param RTCx RTC Instance
|
||||
* @param TimeCounter this value can be from 0 to 0xFFFFFFFF
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC Counter register configured
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_RTC_TIME_SetCounter(RTC_TypeDef *RTCx, uint32_t TimeCounter)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Enter Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
LL_RTC_TIME_Set(RTCx, TimeCounter);
|
||||
status = SUCCESS;
|
||||
}
|
||||
/* Exit Initialization mode */
|
||||
LL_RTC_ExitInitMode(RTCx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set Alarm Counter.
|
||||
* @param RTCx RTC Instance
|
||||
* @param AlarmCounter this value can be from 0 to 0xFFFFFFFF
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC exited from in Init mode
|
||||
* - ERROR: Not applicable
|
||||
*/
|
||||
ErrorStatus LL_RTC_ALARM_SetCounter(RTC_TypeDef *RTCx, uint32_t AlarmCounter)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Enter Initialization mode */
|
||||
if (LL_RTC_EnterInitMode(RTCx) != ERROR)
|
||||
{
|
||||
LL_RTC_ALARM_Set(RTCx, AlarmCounter);
|
||||
status = SUCCESS;
|
||||
}
|
||||
/* Exit Initialization mode */
|
||||
LL_RTC_ExitInitMode(RTCx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Waits until the RTC registers are synchronized with RTC APB clock.
|
||||
* @note The RTC Resynchronization mode is write protected, use the
|
||||
* @ref LL_RTC_DisableWriteProtection before calling this function.
|
||||
* @param RTCx RTC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: RTC registers are synchronised
|
||||
* - ERROR: RTC registers are not synchronised
|
||||
*/
|
||||
ErrorStatus LL_RTC_WaitForSynchro(RTC_TypeDef *RTCx)
|
||||
{
|
||||
__IO uint32_t timeout = RTC_SYNCHRO_TIMEOUT;
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t tmp = 0U;
|
||||
|
||||
/* Check the parameter */
|
||||
assert_param(IS_RTC_ALL_INSTANCE(RTCx));
|
||||
|
||||
/* Clear RSF flag */
|
||||
LL_RTC_ClearFlag_RS(RTCx);
|
||||
|
||||
/* Wait the registers to be synchronised */
|
||||
tmp = LL_RTC_IsActiveFlag_RS(RTCx);
|
||||
while ((timeout != 0U) && (tmp == 0U))
|
||||
{
|
||||
if (LL_SYSTICK_IsActiveCounterFlag() == 1U)
|
||||
{
|
||||
timeout--;
|
||||
}
|
||||
tmp = LL_RTC_IsActiveFlag_RS(RTCx);
|
||||
if (timeout == 0U)
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined(RTC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
512
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_spi.c
Normal file
512
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_spi.c
Normal file
@@ -0,0 +1,512 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_spi.c
|
||||
* @author MCU Application Team
|
||||
* @brief SPI LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_spi.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (SPI1) || defined (SPI2)
|
||||
|
||||
/** @addtogroup SPI_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Constants SPI Private Constants
|
||||
* @{
|
||||
*/
|
||||
/* SPI registers Masks */
|
||||
#define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
|
||||
SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
|
||||
SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_BIDIOE | \
|
||||
SPI_CR1_BIDIMODE)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Macros SPI Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
|
||||
|| ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
|
||||
|
||||
#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
|
||||
|| ((__VALUE__) == LL_SPI_MODE_SLAVE))
|
||||
|
||||
#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
|
||||
|
||||
#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_SPI_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
|
||||
|| ((__VALUE__) == LL_SPI_PHASE_2EDGE))
|
||||
|
||||
#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
|
||||
|
||||
#define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
|
||||
|
||||
#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
|
||||
|| ((__VALUE__) == LL_SPI_MSB_FIRST))
|
||||
|
||||
#define IS_LL_SPI_SLAVE_SPEED_MODE(__VALUE__) (((__VALUE__) == LL_SPI_SLAVE_SPEED_NORMAL) \
|
||||
|| ((__VALUE__) == LL_SPI_SLAVE_SPEED_FAST))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup SPI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the SPI registers to their default reset values.
|
||||
* @param SPIx SPI Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are de-initialized
|
||||
* - ERROR: SPI registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
if (SPIx == SPI1)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_SPI1);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_SPI1);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#if defined(SPI2)
|
||||
if (SPIx == SPI2)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
|
||||
* @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
||||
* SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param SPIx SPI Instance
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value. (Return always SUCCESS)
|
||||
*/
|
||||
ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the SPI Instance SPIx*/
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
/* Check the SPI parameters from SPI_InitStruct*/
|
||||
assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
|
||||
assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
|
||||
assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
|
||||
assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
|
||||
assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
|
||||
assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
|
||||
assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
|
||||
assert_param(IS_LL_SPI_SLAVE_SPEED_MODE(SPI_InitStruct->SlaveSpeedMode));
|
||||
|
||||
if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx CR1 Configuration ------------------------
|
||||
* Configure SPIx CR1 with parameters:
|
||||
* - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
|
||||
* - Master/Slave Mode: SPI_CR1_MSTR bit
|
||||
* - ClockPolarity: SPI_CR1_CPOL bit
|
||||
* - ClockPhase: SPI_CR1_CPHA bit
|
||||
* - NSS management: SPI_CR1_SSM bit
|
||||
* - BaudRate prescaler: SPI_CR1_BR[2:0] bits
|
||||
* - BitOrder: SPI_CR1_LSBFIRST bit
|
||||
* - CRCCalculation: SPI_CR1_CRCEN bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR1,
|
||||
SPI_CR1_CLEAR_MASK,
|
||||
SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode |
|
||||
SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
|
||||
(SPI_InitStruct->NSS & SPI_CR1_SSM) | SPI_InitStruct->BaudRate |
|
||||
SPI_InitStruct->BitOrder);
|
||||
|
||||
/*---------------------------- SPIx CR2 Configuration ------------------------
|
||||
* Configure SPIx CR2 with parameters:
|
||||
* - DataWidth: DS[3:0] bits
|
||||
* - NSS management: SSOE bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR2,
|
||||
(SPI_CR2_DS | SPI_CR2_SSOE | SPI_CR2_SLVFM),
|
||||
(SPI_InitStruct->DataWidth | ((SPI_InitStruct->NSS >> 16U) & SPI_CR2_SSOE) | SPI_InitStruct->SlaveSpeedMode));
|
||||
|
||||
/* Set Rx FIFO to Quarter (1 Byte) in case of 8 Bits mode. No DataPacking by default */
|
||||
if (SPI_InitStruct->DataWidth == LL_SPI_DATAWIDTH_8BIT)
|
||||
{
|
||||
LL_SPI_SetRxFIFOThreshold(SPIx, LL_SPI_RX_FIFO_TH_QUARTER);
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_SPI_SetRxFIFOThreshold(SPIx, LL_SPI_RX_FIFO_TH_HALF);
|
||||
}
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_SPI_InitTypeDef field to default value.
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
/* Set SPI_InitStruct fields to default values */
|
||||
SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
|
||||
SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
|
||||
SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
|
||||
SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
|
||||
SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
|
||||
SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
|
||||
SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
|
||||
SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
|
||||
SPI_InitStruct->SlaveSpeedMode = LL_SPI_SLAVE_SPEED_NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(SPI_I2S_SUPPORT)
|
||||
/** @addtogroup I2S_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup I2S_LL_Private_Constants I2S Private Constants
|
||||
* @{
|
||||
*/
|
||||
/* I2S registers Masks */
|
||||
#define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
|
||||
SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
|
||||
SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD )
|
||||
|
||||
#define I2S_I2SPR_CLEAR_MASK 0x0002U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup I2S_LL_Private_Macros I2S Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_24B) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_32B))
|
||||
|
||||
#define IS_LL_I2S_CPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_I2S_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_MSB) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_LSB) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG))
|
||||
|
||||
#define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_MASTER_TX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_MASTER_RX))
|
||||
|
||||
#define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) \
|
||||
|| ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE))
|
||||
|
||||
#define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) \
|
||||
&& ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) \
|
||||
|| ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT))
|
||||
|
||||
#define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) >= 0x2U)
|
||||
|
||||
#define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) \
|
||||
|| ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup I2S_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the SPI/I2S registers to their default reset values.
|
||||
* @param SPIx SPI Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are de-initialized
|
||||
* - ERROR: SPI registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx)
|
||||
{
|
||||
return LL_SPI_DeInit(SPIx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct.
|
||||
* @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
||||
* SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param SPIx SPI Instance
|
||||
* @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are Initialized
|
||||
* - ERROR: SPI registers are not Initialized
|
||||
*/
|
||||
ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct)
|
||||
{
|
||||
uint32_t i2sdiv = 2U;
|
||||
uint32_t i2sodd = 0U;
|
||||
uint32_t packetlength = 1U;
|
||||
uint32_t tmp;
|
||||
LL_RCC_ClocksTypeDef rcc_clocks;
|
||||
uint32_t sourceclock;
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the I2S parameters */
|
||||
assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
||||
assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
|
||||
assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
|
||||
assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
|
||||
assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput));
|
||||
assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq));
|
||||
assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
|
||||
|
||||
if (LL_I2S_IsEnabled(SPIx) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx I2SCFGR Configuration --------------------
|
||||
* Configure SPIx I2SCFGR with parameters:
|
||||
* - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
|
||||
* - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
|
||||
* - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
|
||||
* - ClockPolarity: SPI_I2SCFGR_CKPOL bit
|
||||
*/
|
||||
|
||||
/* Write to SPIx I2SCFGR */
|
||||
MODIFY_REG(SPIx->I2SCFGR,
|
||||
I2S_I2SCFGR_CLEAR_MASK,
|
||||
I2S_InitStruct->Mode | I2S_InitStruct->Standard |
|
||||
I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
|
||||
SPI_I2SCFGR_I2SMOD);
|
||||
|
||||
/*---------------------------- SPIx I2SPR Configuration ----------------------
|
||||
* Configure SPIx I2SPR with parameters:
|
||||
* - MCLKOutput: SPI_I2SPR_MCKOE bit
|
||||
* - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits
|
||||
*/
|
||||
|
||||
/* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv)
|
||||
* else, default values are used: i2sodd = 0U, i2sdiv = 2U.
|
||||
*/
|
||||
if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT)
|
||||
{
|
||||
/* Check the frame length (For the Prescaler computing)
|
||||
* Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U).
|
||||
*/
|
||||
if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B)
|
||||
{
|
||||
/* Packet length is 32 bits */
|
||||
packetlength = 2U;
|
||||
}
|
||||
|
||||
/* I2S Clock source is System clock: Get System Clock frequency */
|
||||
LL_RCC_GetSystemClocksFreq(&rcc_clocks);
|
||||
|
||||
/* Get the source clock value: based on System Clock value */
|
||||
sourceclock = rcc_clocks.SYSCLK_Frequency;
|
||||
|
||||
/* Compute the Real divider depending on the MCLK output state with a floating point */
|
||||
if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE)
|
||||
{
|
||||
/* MCLK output is enabled */
|
||||
tmp = (((((sourceclock / 256U) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MCLK output is disabled */
|
||||
tmp = (((((sourceclock / (32U * packetlength)) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
||||
}
|
||||
|
||||
/* Remove the floating point */
|
||||
tmp = tmp / 10U;
|
||||
|
||||
/* Check the parity of the divider */
|
||||
i2sodd = (tmp & (uint16_t)0x0001U);
|
||||
|
||||
/* Compute the i2sdiv prescaler */
|
||||
i2sdiv = ((tmp - i2sodd) / 2U);
|
||||
|
||||
/* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
|
||||
i2sodd = (i2sodd << 8U);
|
||||
}
|
||||
|
||||
/* Test if the divider is 1 or 0 or greater than 0xFF */
|
||||
if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
|
||||
{
|
||||
/* Set the default values */
|
||||
i2sdiv = 2U;
|
||||
i2sodd = 0U;
|
||||
}
|
||||
|
||||
/* Write to SPIx I2SPR register the computed value */
|
||||
WRITE_REG(SPIx->I2SPR, i2sdiv | i2sodd | I2S_InitStruct->MCLKOutput);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_I2S_InitTypeDef field to default value.
|
||||
* @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct)
|
||||
{
|
||||
/*--------------- Reset I2S init structure parameters values -----------------*/
|
||||
I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX;
|
||||
I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS;
|
||||
I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B;
|
||||
I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE;
|
||||
I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT;
|
||||
I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set linear and parity prescaler.
|
||||
* @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n
|
||||
* Check Audio frequency table and formulas inside Reference Manual (SPI/I2S).
|
||||
* @param SPIx SPI Instance
|
||||
* @param PrescalerLinear value Min_Data=0x02 and Max_Data=0xFF.
|
||||
* @param PrescalerParity This parameter can be one of the following values:
|
||||
* @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
|
||||
* @arg @ref LL_I2S_PRESCALER_PARITY_ODD
|
||||
* @retval None
|
||||
*/
|
||||
void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity)
|
||||
{
|
||||
/* Check the I2S parameters */
|
||||
assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
||||
assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear));
|
||||
assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity));
|
||||
|
||||
/* Write to SPIx I2SPR */
|
||||
MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV | SPI_I2SPR_ODD, PrescalerLinear | (PrescalerParity << 8U));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* SPI_I2S_SUPPORT */
|
||||
|
||||
#endif /* defined (SPI1) || defined (SPI2) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
1201
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_tim.c
Normal file
1201
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_tim.c
Normal file
@@ -0,0 +1,1201 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_tim.c
|
||||
* @author MCU Application Team
|
||||
* @brief TIM LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_tim.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY32F0XX_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (TIM1) || defined (TIM2) || defined (TIM3) || defined (TIM4) || defined (TIM5) || defined (TIM6) || defined (TIM7) || defined (TIM8) || defined (TIM9) || defined (TIM10) || defined (TIM11) || defined (TIM12) || defined (TIM13) || defined (TIM14) || defined (TIM15) || defined (TIM16) || defined (TIM17)
|
||||
|
||||
/** @addtogroup TIM_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup TIM_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_TIM_COUNTERMODE(__VALUE__) (((__VALUE__) == LL_TIM_COUNTERMODE_UP) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_DOWN) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_DOWN) \
|
||||
|| ((__VALUE__) == LL_TIM_COUNTERMODE_CENTER_UP_DOWN))
|
||||
|
||||
#define IS_LL_TIM_CLOCKDIVISION(__VALUE__) (((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV2) \
|
||||
|| ((__VALUE__) == LL_TIM_CLOCKDIVISION_DIV4))
|
||||
|
||||
#define IS_LL_TIM_OCMODE(__VALUE__) (((__VALUE__) == LL_TIM_OCMODE_FROZEN) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_ACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_INACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_TOGGLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_FORCED_INACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_FORCED_ACTIVE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_PWM1) \
|
||||
|| ((__VALUE__) == LL_TIM_OCMODE_PWM2))
|
||||
|
||||
#define IS_LL_TIM_OCSTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCSTATE_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OCSTATE_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_OCPOLARITY(__VALUE__) (((__VALUE__) == LL_TIM_OCPOLARITY_HIGH) \
|
||||
|| ((__VALUE__) == LL_TIM_OCPOLARITY_LOW))
|
||||
|
||||
#define IS_LL_TIM_OCIDLESTATE(__VALUE__) (((__VALUE__) == LL_TIM_OCIDLESTATE_LOW) \
|
||||
|| ((__VALUE__) == LL_TIM_OCIDLESTATE_HIGH))
|
||||
|
||||
#define IS_LL_TIM_ACTIVEINPUT(__VALUE__) (((__VALUE__) == LL_TIM_ACTIVEINPUT_DIRECTTI) \
|
||||
|| ((__VALUE__) == LL_TIM_ACTIVEINPUT_INDIRECTTI) \
|
||||
|| ((__VALUE__) == LL_TIM_ACTIVEINPUT_TRC))
|
||||
|
||||
#define IS_LL_TIM_ICPSC(__VALUE__) (((__VALUE__) == LL_TIM_ICPSC_DIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV2) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV4) \
|
||||
|| ((__VALUE__) == LL_TIM_ICPSC_DIV8))
|
||||
|
||||
#define IS_LL_TIM_IC_FILTER(__VALUE__) (((__VALUE__) == LL_TIM_IC_FILTER_FDIV1) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N2) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N4) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV1_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV2_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV4_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV8_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV16_N8) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N5) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N6) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_FILTER_FDIV32_N8))
|
||||
|
||||
#define IS_LL_TIM_IC_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
|
||||
|
||||
#define IS_LL_TIM_ENCODERMODE(__VALUE__) (((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI1) \
|
||||
|| ((__VALUE__) == LL_TIM_ENCODERMODE_X2_TI2) \
|
||||
|| ((__VALUE__) == LL_TIM_ENCODERMODE_X4_TI12))
|
||||
|
||||
#define IS_LL_TIM_IC_POLARITY_ENCODER(__VALUE__) (((__VALUE__) == LL_TIM_IC_POLARITY_RISING) \
|
||||
|| ((__VALUE__) == LL_TIM_IC_POLARITY_FALLING))
|
||||
|
||||
#define IS_LL_TIM_OSSR_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSR_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OSSR_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_OSSI_STATE(__VALUE__) (((__VALUE__) == LL_TIM_OSSI_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_OSSI_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_LOCK_LEVEL(__VALUE__) (((__VALUE__) == LL_TIM_LOCKLEVEL_OFF) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_1) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_2) \
|
||||
|| ((__VALUE__) == LL_TIM_LOCKLEVEL_3))
|
||||
|
||||
#define IS_LL_TIM_BREAK_STATE(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_ENABLE))
|
||||
|
||||
#define IS_LL_TIM_BREAK_POLARITY(__VALUE__) (((__VALUE__) == LL_TIM_BREAK_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_TIM_BREAK_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(__VALUE__) (((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_DISABLE) \
|
||||
|| ((__VALUE__) == LL_TIM_AUTOMATICOUTPUT_ENABLE))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup TIM_LL_Private_Functions TIM Private Functions
|
||||
* @{
|
||||
*/
|
||||
static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct);
|
||||
static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup TIM_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TIM_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set TIMx registers to their reset values.
|
||||
* @param TIMx Timer instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: invalid TIMx instance
|
||||
*/
|
||||
ErrorStatus LL_TIM_DeInit(TIM_TypeDef *TIMx)
|
||||
{
|
||||
ErrorStatus result = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(TIMx));
|
||||
|
||||
if (TIMx == TIM1)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM1);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM1);
|
||||
}
|
||||
#if defined(TIM2)
|
||||
if (TIMx == TIM2)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM2);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM2);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM3)
|
||||
else if (TIMx == TIM3)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM3);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM3);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM4)
|
||||
else if (TIMx == TIM4)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM4);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM4);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM5)
|
||||
else if (TIMx == TIM5)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM5);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM5);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM6)
|
||||
else if (TIMx == TIM6)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM6);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM6);
|
||||
}
|
||||
#endif
|
||||
#if defined (TIM7)
|
||||
else if (TIMx == TIM7)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM7);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM7);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM8)
|
||||
else if (TIMx == TIM8)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM8);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM8);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM9)
|
||||
else if (TIMx == TIM9)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM9);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM9);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM10)
|
||||
else if (TIMx == TIM10)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM10);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM10);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM11)
|
||||
else if (TIMx == TIM11)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM11);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM11);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM12)
|
||||
else if (TIMx == TIM12)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM12);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM12);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM13)
|
||||
else if (TIMx == TIM13)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_TIM13);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_TIM13);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM14)
|
||||
else if (TIMx == TIM14)
|
||||
{
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP2_PERIPH_TIM14);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM14);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM15)
|
||||
else if (TIMx == TIM15)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM15);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM15);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM16)
|
||||
else if (TIMx == TIM16)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM16);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM16);
|
||||
}
|
||||
#endif
|
||||
#if defined(TIM17)
|
||||
else if (TIMx == TIM17)
|
||||
{
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_TIM17);
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_TIM17);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
result = ERROR;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the time base unit configuration data structure
|
||||
* to their default values.
|
||||
* @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (time base unit configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_StructInit(LL_TIM_InitTypeDef *TIM_InitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_InitStruct->Prescaler = (uint16_t)0x0000;
|
||||
TIM_InitStruct->CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||
TIM_InitStruct->Autoreload = 0xFFFFFFFFU;
|
||||
TIM_InitStruct->ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||
TIM_InitStruct->RepetitionCounter = (uint8_t)0x00;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx time base unit.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_InitStruct pointer to a @ref LL_TIM_InitTypeDef structure (TIMx time base unit configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_Init(TIM_TypeDef *TIMx, LL_TIM_InitTypeDef *TIM_InitStruct)
|
||||
{
|
||||
uint32_t tmpcr1;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_COUNTERMODE(TIM_InitStruct->CounterMode));
|
||||
assert_param(IS_LL_TIM_CLOCKDIVISION(TIM_InitStruct->ClockDivision));
|
||||
|
||||
tmpcr1 = LL_TIM_ReadReg(TIMx, CR1);
|
||||
|
||||
if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
|
||||
{
|
||||
/* Select the Counter Mode */
|
||||
MODIFY_REG(tmpcr1, (TIM_CR1_DIR | TIM_CR1_CMS), TIM_InitStruct->CounterMode);
|
||||
}
|
||||
|
||||
if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
|
||||
{
|
||||
/* Set the clock division */
|
||||
MODIFY_REG(tmpcr1, TIM_CR1_CKD, TIM_InitStruct->ClockDivision);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR1 */
|
||||
LL_TIM_WriteReg(TIMx, CR1, tmpcr1);
|
||||
|
||||
/* Set the Autoreload value */
|
||||
LL_TIM_SetAutoReload(TIMx, TIM_InitStruct->Autoreload);
|
||||
|
||||
/* Set the Prescaler value */
|
||||
LL_TIM_SetPrescaler(TIMx, TIM_InitStruct->Prescaler);
|
||||
|
||||
if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
|
||||
{
|
||||
/* Set the Repetition Counter value */
|
||||
LL_TIM_SetRepetitionCounter(TIMx, TIM_InitStruct->RepetitionCounter);
|
||||
}
|
||||
|
||||
/* Generate an update event to reload the Prescaler
|
||||
and the repetition counter value (if applicable) immediately */
|
||||
LL_TIM_GenerateEvent_UPDATE(TIMx);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx output channel configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (the output channel configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_OC_StructInit(LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_OC_InitStruct->OCMode = LL_TIM_OCMODE_FROZEN;
|
||||
TIM_OC_InitStruct->OCState = LL_TIM_OCSTATE_DISABLE;
|
||||
TIM_OC_InitStruct->OCNState = LL_TIM_OCSTATE_DISABLE;
|
||||
TIM_OC_InitStruct->CompareValue = 0x00000000U;
|
||||
TIM_OC_InitStruct->OCPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
TIM_OC_InitStruct->OCNPolarity = LL_TIM_OCPOLARITY_HIGH;
|
||||
TIM_OC_InitStruct->OCIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||
TIM_OC_InitStruct->OCNIdleState = LL_TIM_OCIDLESTATE_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel.
|
||||
* @param TIMx Timer Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_TIM_CHANNEL_CH1
|
||||
* @arg @ref LL_TIM_CHANNEL_CH2
|
||||
* @arg @ref LL_TIM_CHANNEL_CH3
|
||||
* @arg @ref LL_TIM_CHANNEL_CH4
|
||||
* @param TIM_OC_InitStruct pointer to a @ref LL_TIM_OC_InitTypeDef structure (TIMx output channel configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx output channel is initialized
|
||||
* - ERROR: TIMx output channel is not initialized
|
||||
*/
|
||||
ErrorStatus LL_TIM_OC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_OC_InitTypeDef *TIM_OC_InitStruct)
|
||||
{
|
||||
ErrorStatus result = ERROR;
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
result = OC1Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH2:
|
||||
result = OC2Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
result = OC3Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH4:
|
||||
result = OC4Config(TIMx, TIM_OC_InitStruct);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx input channel configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_ICInitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (the input channel configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_IC_StructInit(LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_ICInitStruct->ICPolarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_ICInitStruct->ICActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_ICInitStruct->ICPrescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_ICInitStruct->ICFilter = LL_TIM_IC_FILTER_FDIV1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel.
|
||||
* @param TIMx Timer Instance
|
||||
* @param Channel This parameter can be one of the following values:
|
||||
* @arg @ref LL_TIM_CHANNEL_CH1
|
||||
* @arg @ref LL_TIM_CHANNEL_CH2
|
||||
* @arg @ref LL_TIM_CHANNEL_CH3
|
||||
* @arg @ref LL_TIM_CHANNEL_CH4
|
||||
* @param TIM_IC_InitStruct pointer to a @ref LL_TIM_IC_InitTypeDef structure (TIMx input channel configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx output channel is initialized
|
||||
* - ERROR: TIMx output channel is not initialized
|
||||
*/
|
||||
ErrorStatus LL_TIM_IC_Init(TIM_TypeDef *TIMx, uint32_t Channel, LL_TIM_IC_InitTypeDef *TIM_IC_InitStruct)
|
||||
{
|
||||
ErrorStatus result = ERROR;
|
||||
|
||||
switch (Channel)
|
||||
{
|
||||
case LL_TIM_CHANNEL_CH1:
|
||||
result = IC1Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH2:
|
||||
result = IC2Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH3:
|
||||
result = IC3Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
case LL_TIM_CHANNEL_CH4:
|
||||
result = IC4Config(TIMx, TIM_IC_InitStruct);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fills each TIM_EncoderInitStruct field with its default value
|
||||
* @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (encoder interface configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_ENCODER_StructInit(LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_EncoderInitStruct->EncoderMode = LL_TIM_ENCODERMODE_X2_TI1;
|
||||
TIM_EncoderInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_EncoderInitStruct->IC1ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_EncoderInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_EncoderInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
TIM_EncoderInitStruct->IC2Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_EncoderInitStruct->IC2ActiveInput = LL_TIM_ACTIVEINPUT_DIRECTTI;
|
||||
TIM_EncoderInitStruct->IC2Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_EncoderInitStruct->IC2Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the encoder interface of the timer instance.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_EncoderInitStruct pointer to a @ref LL_TIM_ENCODER_InitTypeDef structure (TIMx encoder interface configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_ENCODER_Init(TIM_TypeDef *TIMx, LL_TIM_ENCODER_InitTypeDef *TIM_EncoderInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_ENCODER_INTERFACE_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_ENCODERMODE(TIM_EncoderInitStruct->EncoderMode));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC1Polarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC1ActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC1Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC1Filter));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_EncoderInitStruct->IC2Polarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_EncoderInitStruct->IC2ActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_EncoderInitStruct->IC2Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_EncoderInitStruct->IC2Filter));
|
||||
|
||||
/* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
|
||||
TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Configure TI1 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1ActiveInput >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Filter >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC1Prescaler >> 16U);
|
||||
|
||||
/* Configure TI2 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2ActiveInput >> 8U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Filter >> 8U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_EncoderInitStruct->IC2Prescaler >> 8U);
|
||||
|
||||
/* Set TI1 and TI2 polarity and enable TI1 and TI2 */
|
||||
tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
|
||||
tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC1Polarity);
|
||||
tmpccer |= (uint32_t)(TIM_EncoderInitStruct->IC2Polarity << 4U);
|
||||
tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Set encoder mode */
|
||||
LL_TIM_SetEncoderMode(TIMx, TIM_EncoderInitStruct->EncoderMode);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the TIMx Hall sensor interface configuration data
|
||||
* structure to their default values.
|
||||
* @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (HALL sensor interface configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_HALLSENSOR_StructInit(LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_HallSensorInitStruct->IC1Polarity = LL_TIM_IC_POLARITY_RISING;
|
||||
TIM_HallSensorInitStruct->IC1Prescaler = LL_TIM_ICPSC_DIV1;
|
||||
TIM_HallSensorInitStruct->IC1Filter = LL_TIM_IC_FILTER_FDIV1;
|
||||
TIM_HallSensorInitStruct->CommutationDelay = 0U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the Hall sensor interface of the timer instance.
|
||||
* @note TIMx CH1, CH2 and CH3 inputs connected through a XOR
|
||||
* to the TI1 input channel
|
||||
* @note TIMx slave mode controller is configured in reset mode.
|
||||
Selected internal trigger is TI1F_ED.
|
||||
* @note Channel 1 is configured as input, IC1 is mapped on TRC.
|
||||
* @note Captured value stored in TIMx_CCR1 correspond to the time elapsed
|
||||
* between 2 changes on the inputs. It gives information about motor speed.
|
||||
* @note Channel 2 is configured in output PWM 2 mode.
|
||||
* @note Compare value stored in TIMx_CCR2 corresponds to the commutation delay.
|
||||
* @note OC2REF is selected as trigger output on TRGO.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_HallSensorInitStruct pointer to a @ref LL_TIM_HALLSENSOR_InitTypeDef structure (TIMx HALL sensor interface configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_HALLSENSOR_Init(TIM_TypeDef *TIMx, LL_TIM_HALLSENSOR_InitTypeDef *TIM_HallSensorInitStruct)
|
||||
{
|
||||
uint32_t tmpcr2;
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpsmcr;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_HALL_SENSOR_INTERFACE_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY_ENCODER(TIM_HallSensorInitStruct->IC1Polarity));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_HallSensorInitStruct->IC1Prescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_HallSensorInitStruct->IC1Filter));
|
||||
|
||||
/* Disable the CC1 and CC2: Reset the CC1E and CC2E Bits */
|
||||
TIMx->CCER &= (uint32_t)~(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx SMCR register value */
|
||||
tmpsmcr = LL_TIM_ReadReg(TIMx, SMCR);
|
||||
|
||||
/* Connect TIMx_CH1, CH2 and CH3 pins to the TI1 input */
|
||||
tmpcr2 |= TIM_CR2_TI1S;
|
||||
|
||||
/* OC2REF signal is used as trigger output (TRGO) */
|
||||
tmpcr2 |= LL_TIM_TRGO_OC2REF;
|
||||
|
||||
/* Configure the slave mode controller */
|
||||
tmpsmcr &= (uint32_t)~(TIM_SMCR_TS | TIM_SMCR_SMS);
|
||||
tmpsmcr |= LL_TIM_TS_TI1F_ED;
|
||||
tmpsmcr |= LL_TIM_SLAVEMODE_RESET;
|
||||
|
||||
/* Configure input channel 1 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC);
|
||||
tmpccmr1 |= (uint32_t)(LL_TIM_ACTIVEINPUT_TRC >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Filter >> 16U);
|
||||
tmpccmr1 |= (uint32_t)(TIM_HallSensorInitStruct->IC1Prescaler >> 16U);
|
||||
|
||||
/* Configure input channel 2 */
|
||||
tmpccmr1 &= (uint32_t)~(TIM_CCMR1_OC2M | TIM_CCMR1_OC2FE | TIM_CCMR1_OC2PE | TIM_CCMR1_OC2CE);
|
||||
tmpccmr1 |= (uint32_t)(LL_TIM_OCMODE_PWM2 << 8U);
|
||||
|
||||
/* Set Channel 1 polarity and enable Channel 1 and Channel2 */
|
||||
tmpccer &= (uint32_t)~(TIM_CCER_CC1P | TIM_CCER_CC1NP | TIM_CCER_CC2P | TIM_CCER_CC2NP);
|
||||
tmpccer |= (uint32_t)(TIM_HallSensorInitStruct->IC1Polarity);
|
||||
tmpccer |= (uint32_t)(TIM_CCER_CC1E | TIM_CCER_CC2E);
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx SMCR */
|
||||
LL_TIM_WriteReg(TIMx, SMCR, tmpsmcr);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
/* Write to TIMx CCR2 */
|
||||
LL_TIM_OC_SetCompareCH2(TIMx, TIM_HallSensorInitStruct->CommutationDelay);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set the fields of the Break and Dead Time configuration data structure
|
||||
* to their default values.
|
||||
* @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration data structure)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_TIM_BDTR_StructInit(LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
|
||||
{
|
||||
/* Set the default configuration */
|
||||
TIM_BDTRInitStruct->OSSRState = LL_TIM_OSSR_DISABLE;
|
||||
TIM_BDTRInitStruct->OSSIState = LL_TIM_OSSI_DISABLE;
|
||||
TIM_BDTRInitStruct->LockLevel = LL_TIM_LOCKLEVEL_OFF;
|
||||
TIM_BDTRInitStruct->DeadTime = (uint8_t)0x00;
|
||||
TIM_BDTRInitStruct->BreakState = LL_TIM_BREAK_DISABLE;
|
||||
TIM_BDTRInitStruct->BreakPolarity = LL_TIM_BREAK_POLARITY_LOW;
|
||||
TIM_BDTRInitStruct->AutomaticOutput = LL_TIM_AUTOMATICOUTPUT_DISABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the Break and Dead Time feature of the timer instance.
|
||||
* @note As the bits AOE, BKP, BKE, OSSR, OSSI and DTG[7:0] can be write-locked
|
||||
* depending on the LOCK configuration, it can be necessary to configure all of
|
||||
* them during the first write access to the TIMx_BDTR register.
|
||||
* @note Macro IS_TIM_BREAK_INSTANCE(TIMx) can be used to check whether or not
|
||||
* a timer instance provides a break input.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_BDTRInitStruct pointer to a @ref LL_TIM_BDTR_InitTypeDef structure (Break and Dead Time configuration data structure)
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Break and Dead Time is initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
ErrorStatus LL_TIM_BDTR_Init(TIM_TypeDef *TIMx, LL_TIM_BDTR_InitTypeDef *TIM_BDTRInitStruct)
|
||||
{
|
||||
uint32_t tmpbdtr = 0;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_BREAK_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OSSR_STATE(TIM_BDTRInitStruct->OSSRState));
|
||||
assert_param(IS_LL_TIM_OSSI_STATE(TIM_BDTRInitStruct->OSSIState));
|
||||
assert_param(IS_LL_TIM_LOCK_LEVEL(TIM_BDTRInitStruct->LockLevel));
|
||||
assert_param(IS_LL_TIM_BREAK_STATE(TIM_BDTRInitStruct->BreakState));
|
||||
assert_param(IS_LL_TIM_BREAK_POLARITY(TIM_BDTRInitStruct->BreakPolarity));
|
||||
assert_param(IS_LL_TIM_AUTOMATIC_OUTPUT_STATE(TIM_BDTRInitStruct->AutomaticOutput));
|
||||
|
||||
/* Set the Lock level, the Break enable Bit and the Polarity, the OSSR State,
|
||||
the OSSI State, the dead time value and the Automatic Output Enable Bit */
|
||||
|
||||
/* Set the BDTR bits */
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_DTG, TIM_BDTRInitStruct->DeadTime);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_LOCK, TIM_BDTRInitStruct->LockLevel);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSI, TIM_BDTRInitStruct->OSSIState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_OSSR, TIM_BDTRInitStruct->OSSRState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKE, TIM_BDTRInitStruct->BreakState);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_BKP, TIM_BDTRInitStruct->BreakPolarity);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_AOE, TIM_BDTRInitStruct->AutomaticOutput);
|
||||
MODIFY_REG(tmpbdtr, TIM_BDTR_MOE, TIM_BDTRInitStruct->AutomaticOutput);
|
||||
|
||||
/* Set TIMx_BDTR */
|
||||
LL_TIM_WriteReg(TIMx, BDTR, tmpbdtr);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup TIM_LL_Private_Functions TIM Private Functions
|
||||
* @brief Private functions
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 1.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 1 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC1Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC1_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 1: Reset the CC1E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC1E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC1S);
|
||||
|
||||
/* Set the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr1, TIM_CCMR1_OC1M, TIM_OCInitStruct->OCMode);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1P, TIM_OCInitStruct->OCPolarity);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1E, TIM_OCInitStruct->OCState);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1NP, TIM_OCInitStruct->OCNPolarity << 2U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC1NE, TIM_OCInitStruct->OCNState << 2U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS1, TIM_OCInitStruct->OCIdleState);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS1N, TIM_OCInitStruct->OCNIdleState << 1U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH1(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 2.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 2 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC2Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr1;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC2_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 2: Reset the CC2E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC2E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR1 register value */
|
||||
tmpccmr1 = LL_TIM_ReadReg(TIMx, CCMR1);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr1, TIM_CCMR1_CC2S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr1, TIM_CCMR1_OC2M, TIM_OCInitStruct->OCMode << 8U);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2P, TIM_OCInitStruct->OCPolarity << 4U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2E, TIM_OCInitStruct->OCState << 4U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2NP, TIM_OCInitStruct->OCNPolarity << 6U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC2NE, TIM_OCInitStruct->OCNState << 6U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS2, TIM_OCInitStruct->OCIdleState << 2U);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS2N, TIM_OCInitStruct->OCNIdleState << 3U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR1 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR1, tmpccmr1);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH2(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 3.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 3 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC3Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr2;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC3_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
|
||||
/* Disable the Channel 3: Reset the CC3E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC3E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR2 register value */
|
||||
tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC3S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr2, TIM_CCMR2_OC3M, TIM_OCInitStruct->OCMode);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3P, TIM_OCInitStruct->OCPolarity << 8U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3E, TIM_OCInitStruct->OCState << 8U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the complementary output Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3NP, TIM_OCInitStruct->OCNPolarity << 10U);
|
||||
|
||||
/* Set the complementary output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC3NE, TIM_OCInitStruct->OCNState << 10U);
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS3, TIM_OCInitStruct->OCIdleState << 4U);
|
||||
|
||||
/* Set the complementary output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS3N, TIM_OCInitStruct->OCNIdleState << 5U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR2 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH3(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx output channel 4.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_OCInitStruct pointer to the the TIMx output channel 4 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus OC4Config(TIM_TypeDef *TIMx, LL_TIM_OC_InitTypeDef *TIM_OCInitStruct)
|
||||
{
|
||||
uint32_t tmpccmr2;
|
||||
uint32_t tmpccer;
|
||||
uint32_t tmpcr2;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC4_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_OCMODE(TIM_OCInitStruct->OCMode));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCState));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCPolarity));
|
||||
assert_param(IS_LL_TIM_OCPOLARITY(TIM_OCInitStruct->OCNPolarity));
|
||||
assert_param(IS_LL_TIM_OCSTATE(TIM_OCInitStruct->OCNState));
|
||||
|
||||
/* Disable the Channel 4: Reset the CC4E Bit */
|
||||
CLEAR_BIT(TIMx->CCER, TIM_CCER_CC4E);
|
||||
|
||||
/* Get the TIMx CCER register value */
|
||||
tmpccer = LL_TIM_ReadReg(TIMx, CCER);
|
||||
|
||||
/* Get the TIMx CR2 register value */
|
||||
tmpcr2 = LL_TIM_ReadReg(TIMx, CR2);
|
||||
|
||||
/* Get the TIMx CCMR2 register value */
|
||||
tmpccmr2 = LL_TIM_ReadReg(TIMx, CCMR2);
|
||||
|
||||
/* Reset Capture/Compare selection Bits */
|
||||
CLEAR_BIT(tmpccmr2, TIM_CCMR2_CC4S);
|
||||
|
||||
/* Select the Output Compare Mode */
|
||||
MODIFY_REG(tmpccmr2, TIM_CCMR2_OC4M, TIM_OCInitStruct->OCMode << 8U);
|
||||
|
||||
/* Set the Output Compare Polarity */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC4P, TIM_OCInitStruct->OCPolarity << 12U);
|
||||
|
||||
/* Set the Output State */
|
||||
MODIFY_REG(tmpccer, TIM_CCER_CC4E, TIM_OCInitStruct->OCState << 12U);
|
||||
|
||||
if (IS_TIM_BREAK_INSTANCE(TIMx))
|
||||
{
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCNIdleState));
|
||||
assert_param(IS_LL_TIM_OCIDLESTATE(TIM_OCInitStruct->OCIdleState));
|
||||
|
||||
/* Set the Output Idle state */
|
||||
MODIFY_REG(tmpcr2, TIM_CR2_OIS4, TIM_OCInitStruct->OCIdleState << 6U);
|
||||
}
|
||||
|
||||
/* Write to TIMx CR2 */
|
||||
LL_TIM_WriteReg(TIMx, CR2, tmpcr2);
|
||||
|
||||
/* Write to TIMx CCMR2 */
|
||||
LL_TIM_WriteReg(TIMx, CCMR2, tmpccmr2);
|
||||
|
||||
/* Set the Capture Compare Register value */
|
||||
LL_TIM_OC_SetCompareCH4(TIMx, TIM_OCInitStruct->CompareValue);
|
||||
|
||||
/* Write to TIMx CCER */
|
||||
LL_TIM_WriteReg(TIMx, CCER, tmpccer);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 1.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 1 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC1Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC1_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 1: Reset the CC1E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC1E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR1,
|
||||
(TIM_CCMR1_CC1S | TIM_CCMR1_IC1F | TIM_CCMR1_IC1PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
|
||||
|
||||
/* Select the Polarity and set the CC1E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC1P | TIM_CCER_CC1NP),
|
||||
(TIM_ICInitStruct->ICPolarity | TIM_CCER_CC1E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 2.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 2 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC2Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC2_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 2: Reset the CC2E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC2E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR1,
|
||||
(TIM_CCMR1_CC2S | TIM_CCMR1_IC2F | TIM_CCMR1_IC2PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
|
||||
|
||||
/* Select the Polarity and set the CC2E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC2P | TIM_CCER_CC2NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 4U) | TIM_CCER_CC2E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 3.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 3 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC3Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC3_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 3: Reset the CC3E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC3E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR2,
|
||||
(TIM_CCMR2_CC3S | TIM_CCMR2_IC3F | TIM_CCMR2_IC3PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 16U);
|
||||
|
||||
/* Select the Polarity and set the CC3E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC3P | TIM_CCER_CC3NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 8U) | TIM_CCER_CC3E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure the TIMx input channel 4.
|
||||
* @param TIMx Timer Instance
|
||||
* @param TIM_ICInitStruct pointer to the the TIMx input channel 4 configuration data structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: TIMx registers are de-initialized
|
||||
* - ERROR: not applicable
|
||||
*/
|
||||
static ErrorStatus IC4Config(TIM_TypeDef *TIMx, LL_TIM_IC_InitTypeDef *TIM_ICInitStruct)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_TIM_CC4_INSTANCE(TIMx));
|
||||
assert_param(IS_LL_TIM_IC_POLARITY(TIM_ICInitStruct->ICPolarity));
|
||||
assert_param(IS_LL_TIM_ACTIVEINPUT(TIM_ICInitStruct->ICActiveInput));
|
||||
assert_param(IS_LL_TIM_ICPSC(TIM_ICInitStruct->ICPrescaler));
|
||||
assert_param(IS_LL_TIM_IC_FILTER(TIM_ICInitStruct->ICFilter));
|
||||
|
||||
/* Disable the Channel 4: Reset the CC4E Bit */
|
||||
TIMx->CCER &= (uint32_t)~TIM_CCER_CC4E;
|
||||
|
||||
/* Select the Input and set the filter and the prescaler value */
|
||||
MODIFY_REG(TIMx->CCMR2,
|
||||
(TIM_CCMR2_CC4S | TIM_CCMR2_IC4F | TIM_CCMR2_IC4PSC),
|
||||
(TIM_ICInitStruct->ICActiveInput | TIM_ICInitStruct->ICFilter | TIM_ICInitStruct->ICPrescaler) >> 8U);
|
||||
|
||||
/* Select the Polarity and set the CC4E Bit */
|
||||
MODIFY_REG(TIMx->CCER,
|
||||
(TIM_CCER_CC4P | TIM_CCER_CC4NP),
|
||||
((TIM_ICInitStruct->ICPolarity << 12U) | TIM_CCER_CC4E));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* TIM1 || TIM2 || TIM3 || TIM4 || TIM5 || TIM6 || TIM7 || TIM8 || TIM9 || TIM10 || TIM11 || TIM12 || TIM13 || TIM14 || TIM15 || TIM16 || TIM17 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
388
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_usart.c
Normal file
388
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_usart.c
Normal file
@@ -0,0 +1,388 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_usart.c
|
||||
* @author MCU Application Team
|
||||
* @brief USART LL module driver.
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "py32f0xx_ll_usart.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_bus.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (USART1) || defined (USART2)
|
||||
|
||||
/** @addtogroup USART_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @addtogroup USART_LL_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup USART_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* __BAUDRATE__ The maximum Baud Rate is derived from the maximum clock available
|
||||
* divided by the smallest oversampling used on the USART (i.e. 8) */
|
||||
#define IS_LL_USART_BAUDRATE(__BAUDRATE__) ((__BAUDRATE__) <= 4500000U)
|
||||
|
||||
/* __VALUE__ In case of oversampling by 16 and 8, BRR content must be greater than or equal to 16d. */
|
||||
#define IS_LL_USART_BRR_MIN(__VALUE__) ((__VALUE__) >= 16U)
|
||||
|
||||
/* __VALUE__ BRR content must be lower than or equal to 0xFFFF. */
|
||||
#define IS_LL_USART_BRR_MAX(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
|
||||
|
||||
#define IS_LL_USART_DIRECTION(__VALUE__) (((__VALUE__) == LL_USART_DIRECTION_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_RX) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_TX) \
|
||||
|| ((__VALUE__) == LL_USART_DIRECTION_TX_RX))
|
||||
|
||||
#define IS_LL_USART_PARITY(__VALUE__) (((__VALUE__) == LL_USART_PARITY_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_PARITY_EVEN) \
|
||||
|| ((__VALUE__) == LL_USART_PARITY_ODD))
|
||||
|
||||
#define IS_LL_USART_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_USART_DATAWIDTH_8B) \
|
||||
|| ((__VALUE__) == LL_USART_DATAWIDTH_9B))
|
||||
|
||||
#define IS_LL_USART_OVERSAMPLING(__VALUE__) (((__VALUE__) == LL_USART_OVERSAMPLING_16) \
|
||||
|| ((__VALUE__) == LL_USART_OVERSAMPLING_8))
|
||||
|
||||
#define IS_LL_USART_LASTBITCLKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_LASTCLKPULSE_NO_OUTPUT) \
|
||||
|| ((__VALUE__) == LL_USART_LASTCLKPULSE_OUTPUT))
|
||||
|
||||
#define IS_LL_USART_CLOCKPHASE(__VALUE__) (((__VALUE__) == LL_USART_PHASE_1EDGE) \
|
||||
|| ((__VALUE__) == LL_USART_PHASE_2EDGE))
|
||||
|
||||
#define IS_LL_USART_CLOCKPOLARITY(__VALUE__) (((__VALUE__) == LL_USART_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_USART_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_USART_CLOCKOUTPUT(__VALUE__) (((__VALUE__) == LL_USART_CLOCK_DISABLE) \
|
||||
|| ((__VALUE__) == LL_USART_CLOCK_ENABLE))
|
||||
|
||||
#define IS_LL_USART_STOPBITS(__VALUE__) (((__VALUE__) == LL_USART_STOPBITS_1) \
|
||||
|| ((__VALUE__) == LL_USART_STOPBITS_2))
|
||||
|
||||
#define IS_LL_USART_HWCONTROL(__VALUE__) (((__VALUE__) == LL_USART_HWCONTROL_NONE) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_RTS) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_CTS) \
|
||||
|| ((__VALUE__) == LL_USART_HWCONTROL_RTS_CTS))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup USART_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup USART_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize USART registers (Registers restored to their default values).
|
||||
* @param USARTx USART Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers are de-initialized
|
||||
* - ERROR: USART registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_USART_DeInit(USART_TypeDef *USARTx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
|
||||
if (USARTx == USART1)
|
||||
{
|
||||
/* Force reset of USART clock */
|
||||
LL_APB1_GRP2_ForceReset(LL_APB1_GRP2_PERIPH_USART1);
|
||||
|
||||
/* Release reset of USART clock */
|
||||
LL_APB1_GRP2_ReleaseReset(LL_APB1_GRP2_PERIPH_USART1);
|
||||
}
|
||||
#if defined(USART2)
|
||||
else if (USARTx == USART2)
|
||||
{
|
||||
/* Force reset of USART clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_USART2);
|
||||
|
||||
/* Release reset of USART clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_USART2);
|
||||
}
|
||||
#endif /* USART2 */
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize USART registers according to the specified
|
||||
* parameters in USART_InitStruct.
|
||||
* @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
|
||||
* USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0).
|
||||
* @param USARTx USART Instance
|
||||
* @param USART_InitStruct pointer to a LL_USART_InitTypeDef structure
|
||||
* that contains the configuration information for the specified USART peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers are initialized according to USART_InitStruct content
|
||||
* - ERROR: Problem occurred during USART Registers initialization
|
||||
*/
|
||||
ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO;
|
||||
LL_RCC_ClocksTypeDef rcc_clocks;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate));
|
||||
assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth));
|
||||
assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits));
|
||||
assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity));
|
||||
assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection));
|
||||
assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl));
|
||||
#if defined(USART_CR3_OVER8)
|
||||
assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling));
|
||||
#endif /* USART_OverSampling_Feature */
|
||||
|
||||
/* USART needs to be in disabled state, in order to be able to configure some bits in
|
||||
CRx registers */
|
||||
if (LL_USART_IsEnabled(USARTx) == 0U)
|
||||
{
|
||||
/*---------------------------- USART CR1 Configuration -----------------------
|
||||
* Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters:
|
||||
* - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value
|
||||
* - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value
|
||||
* - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value
|
||||
* - Oversampling: USART_CR3_OVER8 bit according to USART_InitStruct->OverSampling value.
|
||||
*/
|
||||
#if defined(USART_CR3_OVER8)
|
||||
MODIFY_REG(USARTx->CR1,
|
||||
(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
|
||||
USART_CR1_TE | USART_CR1_RE),
|
||||
(USART_InitStruct->DataWidth | USART_InitStruct->Parity |
|
||||
USART_InitStruct->TransferDirection));
|
||||
MODIFY_REG(USARTx->CR3, USART_CR3_OVER8, USART_InitStruct->OverSampling);
|
||||
#else
|
||||
MODIFY_REG(USARTx->CR1,
|
||||
(USART_CR1_M | USART_CR1_PCE | USART_CR1_PS |
|
||||
USART_CR1_TE | USART_CR1_RE),
|
||||
(USART_InitStruct->DataWidth | USART_InitStruct->Parity |
|
||||
USART_InitStruct->TransferDirection));
|
||||
#endif /* USART_OverSampling_Feature */
|
||||
/*---------------------------- USART CR2 Configuration -----------------------
|
||||
* Configure USARTx CR2 (Stop bits) with parameters:
|
||||
* - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value.
|
||||
* - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit().
|
||||
*/
|
||||
LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits);
|
||||
|
||||
/*---------------------------- USART CR3 Configuration -----------------------
|
||||
* Configure USARTx CR3 (Hardware Flow Control) with parameters:
|
||||
* - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to USART_InitStruct->HardwareFlowControl value.
|
||||
*/
|
||||
LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl);
|
||||
|
||||
/*---------------------------- USART BRR Configuration -----------------------
|
||||
* Retrieve Clock frequency used for USART Peripheral
|
||||
*/
|
||||
LL_RCC_GetSystemClocksFreq(&rcc_clocks);
|
||||
periphclk = rcc_clocks.PCLK1_Frequency;
|
||||
|
||||
/* Configure the USART Baud Rate :
|
||||
- valid baud rate value (different from 0) is required
|
||||
- Peripheral clock as returned by RCC service, should be valid (different from 0).
|
||||
*/
|
||||
if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO)
|
||||
&& (USART_InitStruct->BaudRate != 0U))
|
||||
{
|
||||
status = SUCCESS;
|
||||
#if defined(USART_CR3_OVER8)
|
||||
LL_USART_SetBaudRate(USARTx,
|
||||
periphclk,
|
||||
USART_InitStruct->OverSampling,
|
||||
USART_InitStruct->BaudRate);
|
||||
#else
|
||||
LL_USART_SetBaudRate(USARTx,
|
||||
periphclk,
|
||||
USART_InitStruct->BaudRate);
|
||||
#endif /* USART_OverSampling_Feature */
|
||||
/* Check BRR is greater than or equal to 16d */
|
||||
assert_param(IS_LL_USART_BRR_MIN(USARTx->BRR));
|
||||
|
||||
/* Check BRR is greater than or equal to 16d */
|
||||
assert_param(IS_LL_USART_BRR_MAX(USARTx->BRR));
|
||||
}
|
||||
}
|
||||
/* Endif (=> USART not in Disabled state => return ERROR) */
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_USART_InitTypeDef field to default value.
|
||||
* @param USART_InitStruct Pointer to a @ref LL_USART_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
|
||||
void LL_USART_StructInit(LL_USART_InitTypeDef *USART_InitStruct)
|
||||
{
|
||||
/* Set USART_InitStruct fields to default values */
|
||||
USART_InitStruct->BaudRate = 9600U;
|
||||
USART_InitStruct->DataWidth = LL_USART_DATAWIDTH_8B;
|
||||
USART_InitStruct->StopBits = LL_USART_STOPBITS_1;
|
||||
USART_InitStruct->Parity = LL_USART_PARITY_NONE ;
|
||||
USART_InitStruct->TransferDirection = LL_USART_DIRECTION_TX_RX;
|
||||
USART_InitStruct->HardwareFlowControl = LL_USART_HWCONTROL_NONE;
|
||||
#if defined(USART_CR3_OVER8)
|
||||
USART_InitStruct->OverSampling = LL_USART_OVERSAMPLING_16;
|
||||
#endif /* USART_OverSampling_Feature */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize USART Clock related settings according to the
|
||||
* specified parameters in the USART_ClockInitStruct.
|
||||
* @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0),
|
||||
* USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param USARTx USART Instance
|
||||
* @param USART_ClockInitStruct Pointer to a @ref LL_USART_ClockInitTypeDef structure
|
||||
* that contains the Clock configuration information for the specified USART peripheral.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: USART registers related to Clock settings are initialized according to USART_ClockInitStruct content
|
||||
* - ERROR: Problem occurred during USART Registers initialization
|
||||
*/
|
||||
ErrorStatus LL_USART_ClockInit(USART_TypeDef *USARTx, LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check USART Instance and Clock signal output parameters */
|
||||
assert_param(IS_UART_INSTANCE(USARTx));
|
||||
assert_param(IS_LL_USART_CLOCKOUTPUT(USART_ClockInitStruct->ClockOutput));
|
||||
|
||||
/* USART needs to be in disabled state, in order to be able to configure some bits in
|
||||
CRx registers */
|
||||
if (LL_USART_IsEnabled(USARTx) == 0U)
|
||||
{
|
||||
/*---------------------------- USART CR2 Configuration -----------------------*/
|
||||
/* If Clock signal has to be output */
|
||||
if (USART_ClockInitStruct->ClockOutput == LL_USART_CLOCK_DISABLE)
|
||||
{
|
||||
/* Deactivate Clock signal delivery :
|
||||
* - Disable Clock Output: USART_CR2_CLKEN cleared
|
||||
*/
|
||||
LL_USART_DisableSCLKOutput(USARTx);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ensure USART instance is USART capable */
|
||||
assert_param(IS_USART_INSTANCE(USARTx));
|
||||
|
||||
/* Check clock related parameters */
|
||||
assert_param(IS_LL_USART_CLOCKPOLARITY(USART_ClockInitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_USART_CLOCKPHASE(USART_ClockInitStruct->ClockPhase));
|
||||
assert_param(IS_LL_USART_LASTBITCLKOUTPUT(USART_ClockInitStruct->LastBitClockPulse));
|
||||
|
||||
/*---------------------------- USART CR2 Configuration -----------------------
|
||||
* Configure USARTx CR2 (Clock signal related bits) with parameters:
|
||||
* - Enable Clock Output: USART_CR2_CLKEN set
|
||||
* - Clock Polarity: USART_CR2_CPOL bit according to USART_ClockInitStruct->ClockPolarity value
|
||||
* - Clock Phase: USART_CR2_CPHA bit according to USART_ClockInitStruct->ClockPhase value
|
||||
* - Last Bit Clock Pulse Output: USART_CR2_LBCL bit according to USART_ClockInitStruct->LastBitClockPulse value.
|
||||
*/
|
||||
MODIFY_REG(USARTx->CR2,
|
||||
USART_CR2_CLKEN | USART_CR2_CPHA | USART_CR2_CPOL | USART_CR2_LBCL,
|
||||
USART_CR2_CLKEN | USART_ClockInitStruct->ClockPolarity |
|
||||
USART_ClockInitStruct->ClockPhase | USART_ClockInitStruct->LastBitClockPulse);
|
||||
}
|
||||
}
|
||||
/* Else (USART not in Disabled state => return ERROR */
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each field of a @ref LL_USART_ClockInitTypeDef type structure to default value.
|
||||
* @param USART_ClockInitStruct Pointer to a @ref LL_USART_ClockInitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_USART_ClockStructInit(LL_USART_ClockInitTypeDef *USART_ClockInitStruct)
|
||||
{
|
||||
/* Set LL_USART_ClockInitStruct fields with default values */
|
||||
USART_ClockInitStruct->ClockOutput = LL_USART_CLOCK_DISABLE;
|
||||
USART_ClockInitStruct->ClockPolarity = LL_USART_POLARITY_LOW; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
|
||||
USART_ClockInitStruct->ClockPhase = LL_USART_PHASE_1EDGE; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
|
||||
USART_ClockInitStruct->LastBitClockPulse = LL_USART_LASTCLKPULSE_NO_OUTPUT; /* Not relevant when ClockOutput = LL_USART_CLOCK_DISABLE */
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USART1 || USART2 || USART3 || UART4 || UART5 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
|
||||
505
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_utils.c
Normal file
505
py_project/Drivers/PY32F0xx_HAL_Driver/Src/py32f0xx_ll_utils.c
Normal file
@@ -0,0 +1,505 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file py32f0xx_ll_utils.c
|
||||
* @author MCU Application Team
|
||||
* @brief UTILS LL module driver.
|
||||
******************************************************************************
|
||||
* @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_ll_utils.h"
|
||||
#include "py32f0xx_ll_rcc.h"
|
||||
#include "py32f0xx_ll_system.h"
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "py32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
/** @addtogroup PY32F0xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Private_Constants
|
||||
* @{
|
||||
*/
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* Defines used for HSE range */
|
||||
#define UTILS_HSE_FREQUENCY_MIN 4000000U /*!< Frequency min for HSE frequency, in Hz */
|
||||
#define UTILS_HSE_FREQUENCY_MAX 32000000U /*!< Frequency max for HSE frequency, in Hz */
|
||||
|
||||
/* Defines used for PLL input range */
|
||||
#define LL_RCC_PLLINPUT_FREQ_MIN 16000000U /*!< Frequency min for PLL input frequency, in Hz */
|
||||
#define LL_RCC_PLLINPUT_FREQ_MAX 24000000U /*!< Frequency max for PLL input frequency, in Hz */
|
||||
#endif
|
||||
|
||||
/* Defines used for FLASH latency according to HCLK Frequency */
|
||||
#define UTILS_SCALE1_LATENCY1_FREQ 24000000U /*!< HCLK frequency to set FLASH latency 1 in power scale 1 */
|
||||
#define UTILS_SCALE1_LATENCY2_FREQ 48000000U /*!< HCLK frequency to set FLASH latency 2 in power scale 1 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_UTILS_SYSCLK_DIV(__VALUE__) (((__VALUE__) == LL_RCC_SYSCLK_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_8) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_16) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_64) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_128) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_256) \
|
||||
|| ((__VALUE__) == LL_RCC_SYSCLK_DIV_512))
|
||||
|
||||
#define IS_LL_UTILS_APB1_DIV(__VALUE__) (((__VALUE__) == LL_RCC_APB1_DIV_1) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_2) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_4) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_8) \
|
||||
|| ((__VALUE__) == LL_RCC_APB1_DIV_16))
|
||||
|
||||
|
||||
#define IS_LL_UTILS_HSE_BYPASS(__STATE__) (((__STATE__) == LL_UTILS_HSEBYPASS_ON) \
|
||||
|| ((__STATE__) == LL_UTILS_HSEBYPASS_OFF))
|
||||
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
#define IS_LL_UTILS_HSE_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= UTILS_HSE_FREQUENCY_MIN) && ((__FREQUENCY__) <= UTILS_HSE_FREQUENCY_MAX))
|
||||
|
||||
#define IS_LL_UTILS_PLL_INPUT_FREQUENCY(__FREQUENCY__) (((__FREQUENCY__) >= LL_RCC_PLLINPUT_FREQ_MIN) && ((__FREQUENCY__) <= LL_RCC_PLLINPUT_FREQ_MAX))
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup UTILS_LL_Private_Functions UTILS Private functions
|
||||
* @{
|
||||
*/
|
||||
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct);
|
||||
static ErrorStatus UTILS_PLL_IsBusy(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup UTILS_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_LL_EF_DELAY
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function configures the Cortex-M SysTick source to have 1ms time base.
|
||||
* @note When a RTOS is used, it is recommended to avoid changing the Systick
|
||||
* configuration by calling this function, for a delay use rather osDelay RTOS service.
|
||||
* @param HCLKFrequency HCLK frequency in Hz
|
||||
* @note HCLK frequency can be calculated thanks to RCC helper macro or function @ref LL_RCC_GetSystemClocksFreq
|
||||
* @retval None
|
||||
*/
|
||||
void LL_Init1msTick(uint32_t HCLKFrequency)
|
||||
{
|
||||
/* Use frequency provided in argument */
|
||||
LL_InitTick(HCLKFrequency, 1000U);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function provides accurate delay (in milliseconds) based
|
||||
* on SysTick counter flag
|
||||
* @note When a RTOS is used, it is recommended to avoid using blocking delay
|
||||
* and use rather osDelay service.
|
||||
* @note To respect 1ms timebase, user should call @ref LL_Init1msTick function which
|
||||
* will configure Systick to 1ms
|
||||
* @param Delay specifies the delay time length, in milliseconds.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_mDelay(uint32_t Delay)
|
||||
{
|
||||
__IO uint32_t tmp = SysTick->CTRL; /* Clear the COUNTFLAG first */
|
||||
uint32_t tmpDelay; /* MISRAC2012-Rule-17.8 */
|
||||
/* Add this code to indicate that local variable is not used */
|
||||
((void)tmp);
|
||||
tmpDelay = Delay;
|
||||
/* Add a period to guaranty minimum wait */
|
||||
if (tmpDelay < LL_MAX_DELAY)
|
||||
{
|
||||
tmpDelay ++;
|
||||
}
|
||||
|
||||
while (tmpDelay != 0U)
|
||||
{
|
||||
if ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0U)
|
||||
{
|
||||
tmpDelay --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup UTILS_EF_SYSTEM
|
||||
* @brief System Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### System Configuration functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
System, AHB and APB1 buses clocks configuration
|
||||
|
||||
(+) The maximum frequency of the SYSCLK, HCLK, PCLK1 is 48000000 Hz.
|
||||
@endverbatim
|
||||
@internal
|
||||
Depending on the device voltage range, the maximum frequency should be
|
||||
adapted accordingly:
|
||||
|
||||
(++) Table 1. HCLK clock frequency.
|
||||
(++) +-------------------------------------------------------+
|
||||
(++) | Latency | HCLK clock frequency (MHz) |
|
||||
(++) | |-------------------------------------|
|
||||
(++) | | voltage range 1 | voltage range 2 |
|
||||
(++) | | 1.08V - 1.32V | 0.9 V - 1.10V |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |0WS(1 CPU cycles)| HCLK <= 24 | HCLK <= 8 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
(++) |1WS(2 CPU cycles)| HCLK <= 48 | HCLK <= 16 |
|
||||
(++) |-----------------|------------------|------------------|
|
||||
|
||||
@endinternal
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This function sets directly SystemCoreClock CMSIS variable.
|
||||
* @note Variable can be calculated also through SystemCoreClockUpdate function.
|
||||
* @param HCLKFrequency HCLK frequency in Hz (can be calculated thanks to RCC helper macro)
|
||||
* @retval None
|
||||
*/
|
||||
void LL_SetSystemCoreClock(uint32_t HCLKFrequency)
|
||||
{
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock = HCLKFrequency;
|
||||
}
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/**
|
||||
* @brief This function configures system clock with HSI as clock source of the PLL
|
||||
* @note The application need to ensure that PLL is disabled.
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: configuration done
|
||||
* - ERROR: frequency configuration not done
|
||||
*/
|
||||
ErrorStatus LL_PLL_ConfigSystemClock_HSI(LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status;
|
||||
uint32_t pllfreq;
|
||||
|
||||
/* Check if one of the PLL is enabled */
|
||||
if (UTILS_PLL_IsBusy() == SUCCESS)
|
||||
{
|
||||
/* Check if the new PLL input frequency is correct */
|
||||
if (!IS_LL_UTILS_PLL_INPUT_FREQUENCY(LL_RCC_HSI_GetFreq()))
|
||||
{
|
||||
/* the new PLL input frequency is error */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Calculate the new PLL output frequency */
|
||||
pllfreq = 2 * LL_RCC_HSI_GetFreq();
|
||||
|
||||
/* Enable HSI if not enabled */
|
||||
if (LL_RCC_HSI_IsReady() != 1U)
|
||||
{
|
||||
LL_RCC_HSI_Enable();
|
||||
while (LL_RCC_HSI_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for HSI ready */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure PLL */
|
||||
LL_RCC_PLL_SetMainSource(LL_RCC_PLLSOURCE_HSI);
|
||||
|
||||
/* Enable PLL and switch system clock to PLL */
|
||||
status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Current PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function configures system clock with HSE as clock source of the PLL
|
||||
* @note The application need to ensure that PLL is disabled.
|
||||
* @param HSEFrequency Value between Min_Data = 4000000 and Max_Data = 48000000
|
||||
* @param HSEBypass This parameter can be one of the following values:
|
||||
* @arg @ref LL_UTILS_HSEBYPASS_ON
|
||||
* @arg @ref LL_UTILS_HSEBYPASS_OFF
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Max frequency configuration done
|
||||
* - ERROR: Max frequency configuration not done
|
||||
*/
|
||||
ErrorStatus LL_PLL_ConfigSystemClock_HSE(uint32_t HSEFrequency, uint32_t HSEBypass, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status;
|
||||
uint32_t pllfreq;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_LL_UTILS_HSE_FREQUENCY(HSEFrequency));
|
||||
assert_param(IS_LL_UTILS_HSE_BYPASS(HSEBypass));
|
||||
|
||||
/* Check if one of the PLL is enabled */
|
||||
if (UTILS_PLL_IsBusy() == SUCCESS)
|
||||
{
|
||||
/* Check if the new PLL input frequency is correct */
|
||||
if (!IS_LL_UTILS_PLL_INPUT_FREQUENCY(HSEFrequency))
|
||||
{
|
||||
/* the new PLL input frequency is error */
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Calculate the new PLL output frequency */
|
||||
pllfreq = HSEFrequency * 2;
|
||||
|
||||
/* Enable HSE if not enabled */
|
||||
if (LL_RCC_HSE_IsReady() != 1U)
|
||||
{
|
||||
/* Set frequency range of the HSE */
|
||||
LL_RCC_HSE_SetFreqRegion(LL_RCC_HSE_16_32MHz);
|
||||
|
||||
/* Check if need to enable HSE bypass feature or not */
|
||||
if (HSEBypass == LL_UTILS_HSEBYPASS_ON)
|
||||
{
|
||||
LL_RCC_HSE_EnableBypass();
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_RCC_HSE_DisableBypass();
|
||||
}
|
||||
|
||||
/* Enable HSE */
|
||||
LL_RCC_HSE_Enable();
|
||||
while (LL_RCC_HSE_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for HSE ready */
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure PLL */
|
||||
LL_RCC_PLL_SetMainSource(LL_RCC_PLLSOURCE_HSE);
|
||||
|
||||
/* Enable PLL and switch system clock to PLL */
|
||||
status = UTILS_EnablePLLAndSwitchSystem(pllfreq, UTILS_ClkInitStruct);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Current PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update number of Flash wait states in line with new frequency and current
|
||||
* voltage range.
|
||||
* @param HCLKFrequency HCLK frequency
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: Latency has been modified
|
||||
* - ERROR: Latency cannot be modified
|
||||
*/
|
||||
ErrorStatus LL_SetFlashLatency(uint32_t HCLKFrequency)
|
||||
{
|
||||
uint32_t timeout;
|
||||
uint32_t getlatency;
|
||||
uint32_t latency;
|
||||
ErrorStatus status;
|
||||
|
||||
/* Frequency cannot be equal to 0 or greater than max clock */
|
||||
if ((HCLKFrequency == 0U) || (HCLKFrequency > UTILS_SCALE1_LATENCY2_FREQ))
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HCLKFrequency > UTILS_SCALE1_LATENCY1_FREQ)
|
||||
{
|
||||
/* 24 < HCLK <= 48 => 1WS (2 CPU cycles) */
|
||||
latency = LL_FLASH_LATENCY_1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* else HCLKFrequency < 24MHz default LL_FLASH_LATENCY_0 0WS */
|
||||
latency = LL_FLASH_LATENCY_0;
|
||||
}
|
||||
}
|
||||
|
||||
LL_FLASH_SetLatency(latency);
|
||||
|
||||
/* Check that the new number of wait states is taken into account to access the Flash
|
||||
memory by reading the FLASH_ACR register */
|
||||
timeout = 2u;
|
||||
do
|
||||
{
|
||||
/* Wait for Flash latency to be updated */
|
||||
getlatency = LL_FLASH_GetLatency();
|
||||
timeout--;
|
||||
}
|
||||
while ((getlatency != latency) && (timeout > 0u));
|
||||
|
||||
if (getlatency != latency)
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = SUCCESS;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#if defined(RCC_PLL_SUPPORT)
|
||||
/** @addtogroup UTILS_LL_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Function to check that PLL can be modified
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: PLL modification can be done
|
||||
* - ERROR: PLL is busy
|
||||
*/
|
||||
static ErrorStatus UTILS_PLL_IsBusy(void)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check if PLL is busy*/
|
||||
if (LL_RCC_PLL_IsReady() != 0U)
|
||||
{
|
||||
/* PLL configuration cannot be modified */
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to enable PLL and switch system clock to PLL
|
||||
* @param SYSCLK_Frequency SYSCLK frequency
|
||||
* @param UTILS_ClkInitStruct pointer to a @ref LL_UTILS_ClkInitTypeDef structure that contains
|
||||
* the configuration information for the BUS prescalers.
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: No problem to switch system to PLL
|
||||
* - ERROR: Problem to switch system to PLL
|
||||
*/
|
||||
static ErrorStatus UTILS_EnablePLLAndSwitchSystem(uint32_t SYSCLK_Frequency, LL_UTILS_ClkInitTypeDef *UTILS_ClkInitStruct)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
uint32_t hclk_frequency;
|
||||
|
||||
assert_param(IS_LL_UTILS_SYSCLK_DIV(UTILS_ClkInitStruct->AHBCLKDivider));
|
||||
assert_param(IS_LL_UTILS_APB1_DIV(UTILS_ClkInitStruct->APB1CLKDivider));
|
||||
|
||||
/* Calculate HCLK frequency */
|
||||
hclk_frequency = __LL_RCC_CALC_HCLK_FREQ(SYSCLK_Frequency, UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
|
||||
/* Increasing the number of wait states because of higher CPU frequency */
|
||||
if (SystemCoreClock < hclk_frequency)
|
||||
{
|
||||
/* Set FLASH latency to highest latency */
|
||||
status = LL_SetFlashLatency(hclk_frequency);
|
||||
}
|
||||
|
||||
/* Update system clock configuration */
|
||||
if (status == SUCCESS)
|
||||
{
|
||||
/* Enable PLL */
|
||||
LL_RCC_PLL_Enable();
|
||||
while (LL_RCC_PLL_IsReady() != 1U)
|
||||
{
|
||||
/* Wait for PLL ready */
|
||||
}
|
||||
|
||||
/* Sysclk activation on the main PLL */
|
||||
LL_RCC_SetAHBPrescaler(UTILS_ClkInitStruct->AHBCLKDivider);
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
|
||||
while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
|
||||
{
|
||||
/* Wait for system clock switch to PLL */
|
||||
}
|
||||
|
||||
/* Set APB1 prescaler*/
|
||||
LL_RCC_SetAPB1Prescaler(UTILS_ClkInitStruct->APB1CLKDivider);
|
||||
}
|
||||
|
||||
/* Decreasing the number of wait states because of lower CPU frequency */
|
||||
if (SystemCoreClock > hclk_frequency)
|
||||
{
|
||||
/* Set FLASH latency to lowest latency */
|
||||
status = LL_SetFlashLatency(hclk_frequency);
|
||||
}
|
||||
|
||||
/* Update SystemCoreClock variable */
|
||||
if (status == SUCCESS)
|
||||
{
|
||||
LL_SetSystemCoreClock(hclk_frequency);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT Puya *****END OF FILE****/
|
||||
Reference in New Issue
Block a user