Добавлена терминалка от андрея, +проект вынесен в отдельную папку

This commit is contained in:
2025-03-05 17:23:57 +03:00
parent 424ca121f8
commit fad121a9fd
442 changed files with 56 additions and 50 deletions

View File

@@ -0,0 +1,714 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_HAL_Driver
* @{
*/
/** @addtogroup HAL
* @brief HAL module driver
* @{
*/
#ifdef HAL_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup HAL_Private_Constants HAL Private Constants
* @{
*/
/**
* @brief PY32F002B HAL Driver version number
*/
#define __PY32F002B_HAL_VERSION_MAIN (0x01U) /*!< [31:24] main version */
#define __PY32F002B_HAL_VERSION_SUB1 (0x00U) /*!< [23:16] sub1 version */
#define __PY32F002B_HAL_VERSION_SUB2 (0x00U) /*!< [15:8] sub2 version */
#define __PY32F002B_HAL_VERSION_RC (0x00U) /*!< [7:0] release candidate */
#define __PY32F002B_HAL_VERSION ((__PY32F002B_HAL_VERSION_MAIN << 24U)\
|(__PY32F002B_HAL_VERSION_SUB1 << 16U)\
|(__PY32F002B_HAL_VERSION_SUB2 << 8U )\
|(__PY32F002B_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
* PY32F002B_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 __PY32F002B_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
@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
* @{
*/
/**
* @brief Set memory mapping at address 0x00000000
* @param Memory This parameter can be one of the following values:
* @arg @ref SYSCFG_BOOT_MAINFLASH
* @arg @ref SYSCFG_BOOT_SYSTEMFLASH
* @arg @ref SYSCFG_BOOT_SRAM
* @retval None
*/
void HAL_SYSCFG_SetRemapMemory(uint32_t Memory)
{
MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_MEM_MODE, Memory);
}
/**
* @brief Get memory mapping at address 0x00000000
* @retval Returned value can be one of the following values:
* @arg @ref SYSCFG_BOOT_MAINFLASH
* @arg @ref SYSCFG_BOOT_SYSTEMFLASH
* @arg @ref SYSCFG_BOOT_SRAM
*/
uint32_t HAL_SYSCFG_GetRemapMemory(void)
{
return (uint32_t)(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_MEM_MODE));
}
/**
* @brief Set TIM1 CH1 Input Source.
* @param Source TIM1 CH1 Input Source.
* This parameter can be one of the following values:
* @arg SYSCFG_CH1_SRC_TIM1_GPIO
* @arg SYSCFG_CH1_SRC_TIM1_COMP1
* @arg SYSCFG_CH1_SRC_TIM1_COMP2
* @retval None
*/
void HAL_SYSCFG_SetTIM1CH1Source(uint32_t Source)
{
MODIFY_REG(SYSCFG->CFGR1, SYSCFG_CFGR1_TIM1_IC1_SRC, Source);
}
/**
* @brief Get TIM1 CH1 Input Source.
* @retval Returned value can be one of the following values:
* @arg @ref SYSCFG_CH1_SRC_TIM1_GPIO
* @arg @ref SYSCFG_CH1_SRC_TIM1_COMP1
* @arg @ref SYSCFG_CH1_SRC_TIM1_COMP2
*/
uint32_t HAL_SYSCFG_GetTIM1CH1Source(void)
{
return (uint32_t)(READ_BIT(SYSCFG->CFGR1, SYSCFG_CFGR1_TIM1_IC1_SRC));
}
/**
* @brief Enable I2C Fast mode plus
* @note Depending on devices and packages, some IOs may not be available.
* Refer to device datasheet for IOs availability.
* @param I2CFastModePlus This parameter can be a combination of the following values:
* @arg @ref SYSCFG_I2C_FMP_PA2
* @arg @ref SYSCFG_I2C_FMP_PB3
* @arg @ref SYSCFG_I2C_FMP_PB4
* @arg @ref SYSCFG_I2C_FMP_PB6
* @retval None
*/
void HAL_SYSCFG_EnableI2CFastModePlus(uint32_t I2CFastModePlus)
{
SET_BIT(SYSCFG->CFGR1, I2CFastModePlus);
}
/**
* @brief Disable I2C Fast mode plus
* @note Depending on devices and packages, some IOs may not be available.
* Refer to device datasheet for IOs availability.
* @param I2CFastModePlus This parameter can be a combination of the following values:
* @arg @ref SYSCFG_I2C_FMP_PA2
* @arg @ref SYSCFG_I2C_FMP_PB3
* @arg @ref SYSCFG_I2C_FMP_PB4
* @arg @ref SYSCFG_I2C_FMP_PB6
* @retval None
*/
void HAL_SYSCFG_DisableI2CFastModePlus(uint32_t I2CFastModePlus)
{
CLEAR_BIT(SYSCFG->CFGR1, I2CFastModePlus);
}
#if defined(SYSCFG_CFGR2_ETR_SRC_TIM1)
/**
* @brief Set TIM1 ETR Source
* @param ETRSource TIM1 ETR Source.
* This parameter can be one of the following values:
* @arg SYSCFG_ETR_SRC_TIM1_GPIO: GPIO for TIM1 ETR Source
* @arg SYSCFG_ETR_SRC_TIM1_COMP1: COMP1 for TIM1 ETR Source
* @arg SYSCFG_ETR_SRC_TIM1_COMP2: COMP2 for TIM1 ETR Source
* @arg SYSCFG_ETR_SRC_TIM1_ADC: ADC for TIM1 ETR Source
* @retval None
*/
void HAL_SYSCFG_TIM1ETRSource(uint32_t ETRSource)
{
MODIFY_REG(SYSCFG->CFGR2, SYSCFG_CFGR2_ETR_SRC_TIM1, ETRSource);
}
#endif
#if (defined(SYSCFG_GPIO_ENS_PA_ENS) || defined(SYSCFG_GPIO_ENS_PB_ENS) || defined(SYSCFG_GPIO_ENS_PC_ENS))
/**
* @brief Enable GPIO Noise Filter
* @note Depending on devices and packages, some IOs may not be available.
* Refer to device datasheet for IOs availability.
* @param GPIOx where x can be (A..C) to select the GPIO peripheral for PY32F002B family
* @param GPIO_Pin specifies the pin to be Noise Filter
* This parameter can be any combination of GPIO_Pin_x where x can be (0..7).
* @retval None
*/
void HAL_SYSCFG_EnableGPIONoiseFilter(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
if(GPIOx == GPIOA)
{
SET_BIT(SYSCFG->GPIO_ENS, GPIO_Pin);
}
else if(GPIOx == GPIOB)
{
SET_BIT(SYSCFG->GPIO_ENS, (GPIO_Pin << 8U));
}
else if(GPIOx == GPIOC)
{
SET_BIT(SYSCFG->GPIO_ENS, (GPIO_Pin << 16U));
}
else
{
}
}
/**
* @brief Disable GPIO Noise Filter
* @note Depending on devices and packages, some IOs may not be available.
* Refer to device datasheet for IOs availability.
* @param GPIOx where x can be (A..C) to select the GPIO peripheral for PY32F002B family
* @param GPIO_Pin specifies the pin to be Noise Filter
* This parameter can be any combination of GPIO_Pin_x where x can be (0..7).
* @retval None
*/
void HAL_SYSCFG_DisableGPIONoiseFilter(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
/* Check the parameters */
assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
assert_param(IS_GPIO_PIN(GPIO_Pin));
if(GPIOx == GPIOA)
{
CLEAR_BIT(SYSCFG->GPIO_ENS, GPIO_Pin);
}
else if(GPIOx == GPIOB)
{
CLEAR_BIT(SYSCFG->GPIO_ENS, (GPIO_Pin << 8U));
}
else if(GPIOx == GPIOC)
{
CLEAR_BIT(SYSCFG->GPIO_ENS, (GPIO_Pin << 16U));
}
else
{
}
}
#endif
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,2181 @@
/**
******************************************************************************
* @file py32f002b_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
*
@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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_HAL_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);
/**
* @}
*/
/* 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));
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 */
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) );
/* 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;
}
}
/* 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 ) );
/* Reset register ISR */
__HAL_ADC_CLEAR_FLAG(hadc, (ADC_FLAG_AWD | ADC_FLAG_OVR |
ADC_FLAG_EOS | ADC_FLAG_EOC |
ADC_FLAG_EOSMP ) );
/* Reset register CR */
/* Bits ADC_CR_ADCAL, ADC_CR_ADSTP, ADC_CR_ADSTART are in access mode */
/* "read-set": no direct reset applicable. */
hadc->Instance->CR &= ~(ADC_CR_VREFBUFF_SEL | ADC_CR_VREF_BUFFERE);
/* Reset register CFGR1 */
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 );
/* 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);
#if defined(ADC_CHSELR_CHSEL10)
/* Reset register CHSELR */
hadc->Instance->CHSELR &= ~(ADC_CHSELR_CHSEL10 | 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 );
#else
/* Reset register CHSELR */
hadc->Instance->CHSELR &= ~(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 );
#endif
/* 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;
}
/**
* @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_8 is selected, enable Temp. sensor measurement path. */
/* If Channel_9 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 the ADC VrefBuf
* @param hadc: ADC handle
* @param VrefBuf the ADC VrefBuf.
* This parameter can be one of the following values:
* @arg ADC_VREFBUF_VCCA: VCCA
* @arg ADC_VREFBUF_1P5V: 1P5V
* @retval HAL status
*/
HAL_StatusTypeDef HAL_ADC_ConfigVrefBuf(ADC_HandleTypeDef* hadc, uint32_t VrefBuf)
{
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
assert_param(IS_ADC_VREFBUF(VrefBuf));
/* Process locked */
__HAL_LOCK(hadc);
MODIFY_REG(hadc->Instance->CR, ADC_CR_VREF_BUFFERE | ADC_CR_VREFBUFF_SEL ,VrefBuf);
if(VrefBuf != ADC_VREFBUF_VCCA)
{
SET_BIT(ADC->CCR,ADC_CCR_VREFEN);
}
/* 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;
}
/**
* @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;
/* 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);
/* 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;
}
}
/* 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;
}
/**
* @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() ).
* @param hadc: ADC handle
* @param CalibSamplingTime ADC Calibration Sample Time
* This parameter can be one of the following values:
* @arg ADC_CALIBSAMPLETIME_1CYCLE: 1 ADC CYCLE
* @arg ADC_CALIBSAMPLETIME_2CYCLES: 2 ADC CYCLES
* @arg ADC_CALIBSAMPLETIME_4CYCLES: 4 ADC CYCLES
* @arg ADC_CALIBSAMPLETIME_8CYCLES: 8 ADC CYCLES
* @param CalibSelection ADC Calibration Selection
* This parameter can be one of the following values:
* @arg ADC_CALIBSELECTION_ONLYOFFSET: Only Calibrate the OFFSET
* @arg ADC_CALIBSELECTION_OFFSET_CAPACITANCE: Calibrate the OFFSET and CAPACITANCE
* @retval HAL status
*/
HAL_StatusTypeDef HAL_ADC_Calibration_SetAndStart(ADC_HandleTypeDef* hadc,uint32_t CalibSamplingTime,uint32_t CalibSelection)
{
HAL_StatusTypeDef tmp_hal_status = HAL_OK;
uint32_t tickstart = 0U;
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
assert_param(IS_ADC_CALIBRATION_SAMPLETIME(CalibSamplingTime));
assert_param(IS_ADC_CALIBRATION_SELECTION(CalibSelection));
/* 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);
hadc->Instance->CCSR &= ~( ADC_CCSR_CALSMP | ADC_CCSR_CALSEL );
hadc->Instance->CCSR |= ( CalibSamplingTime | CalibSelection );
/* 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;
}
}
/* 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;
}
/**
* @brief Get ADC Calibration Status.
* @param hadc ADC handle
* @retval HAL ADC Calibration status
*/
HAL_ADCCalibStatusTypeDef HAL_ADC_Calibration_GetStatus(ADC_HandleTypeDef* hadc)
{
/* Check the parameters */
assert_param(IS_ADC_ALL_INSTANCE(hadc->Instance));
ADC_STATE_CLR_SET(hadc->State,
HAL_ADC_STATE_READY,
HAL_ADC_STATE_BUSY_INTERNAL);
/* Check CALON Status */
if(READ_BIT(hadc->Instance->CCSR, ADC_CCSR_CALON) == ADC_CCSR_CALON)
{
ADC_STATE_CLR_SET(hadc->State,
HAL_ADC_STATE_BUSY_INTERNAL,
HAL_ADC_STATE_ERROR_INTERNAL);
return HAL_ADCCALIBERROR;
}
/* Check OFFSUC Status */
if(READ_BIT(hadc->Instance->CCSR, ADC_CCSR_OFFSUC) != ADC_CCSR_OFFSUC)
{
ADC_STATE_CLR_SET(hadc->State,
HAL_ADC_STATE_BUSY_INTERNAL,
HAL_ADC_STATE_ERROR_INTERNAL);
return HAL_ADCCALIBOFFFAIL;
}
/* Check CAPSUC Status */
if(READ_BIT(hadc->Instance->CCSR, ADC_CCSR_CALSEL) == ADC_CCSR_CALSEL)
{
if(READ_BIT(hadc->Instance->CCSR, ADC_CCSR_CAPSUC) != ADC_CCSR_CAPSUC)
{
ADC_STATE_CLR_SET(hadc->State,
HAL_ADC_STATE_BUSY_INTERNAL,
HAL_ADC_STATE_ERROR_INTERNAL);
return HAL_ADCCALIBCAPFAIL;
}
}
ADC_STATE_CLR_SET(hadc->State,
HAL_ADC_STATE_BUSY_INTERNAL,
HAL_ADC_STATE_READY);
/* Return function status */
return HAL_ADCCALIBOK;
}
/**
* @}
*/
#endif /* HAL_ADC_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,960 @@
/**
******************************************************************************
* @file py32f002b_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 PY32F002B 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 output polarity
(++) 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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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.
* @param hcomp COMP handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_COMP_Init(COMP_HandleTypeDef *hcomp)
{
uint32_t tmp_csr;
uint32_t exti_line;
__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
{
/* 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_TRIGGERMODE(hcomp->Init.TriggerMode));
assert_param(IS_COMP_WINDOWMODE(hcomp->Init.WindowMode));
assert_param(IS_COMP_VREFSRC(hcomp->Init.VrefSrc));
assert_param(IS_COMP_VREFDIV(hcomp->Init.VrefDiv));
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 */
}
/* Set COMP parameters */
tmp_csr = ( hcomp->Init.InputMinus
| hcomp->Init.InputPlus
| hcomp->Init.OutputPol
);
/* Set parameters in COMP register */
/* Note: Update all bits except read-only, lock and enable bits */
MODIFY_REG(hcomp->Instance->CSR,
COMP_CSR_COMP_OUT |
COMP_CSR_POLARITY | COMP_CSR_WINMODE | COMP_CSR_INPSEL |
COMP_CSR_INNSEL | 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)));
}
MODIFY_REG(COMP12_COMMON->CSR_ODD, COMP_CSR_COMP_VCSEL, hcomp->Init.VrefSrc);
MODIFY_REG(COMP12_COMMON->CSR_ODD, COMP_CSR_COMP_VCDIV_EN | COMP_CSR_COMP_VCDIV, hcomp->Init.VrefDiv);
/* 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_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);
}
/* 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.
* @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
{
/* Check the parameter */
assert_param(IS_COMP_ALL_INSTANCE(hcomp->Instance));
/* Set COMP_CSR register to reset value */
WRITE_REG(hcomp->Instance->CSR, 0x00000000UL);
/* Set COMP_FR register to reset value */
WRITE_REG(hcomp->Instance->FR, 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
{
/* 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
{
/* 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
{
/* 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;
}
}
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****/

View File

@@ -0,0 +1,338 @@
/**
******************************************************************************
* @file py32f002b_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 py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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.
* @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****/

View File

@@ -0,0 +1,333 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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****/

View File

@@ -0,0 +1,565 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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****/

View File

@@ -0,0 +1,952 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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] = {0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF011C, 0x1FFF0130, 0x1FFF011C, 0x1FFF011C};
/**
* @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 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 User 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_IWDG_STOP
* @arg @ref FLASH_OB_USER_IWDG_SW
* @arg @ref FLASH_OB_USER_SWD_NRST
* @retval None
*/
static void FLASH_OB_OptrConfig(uint32_t UserType, uint32_t UserConfig)
{
uint32_t optr;
/* Check the parameters */
assert_param(IS_OB_USER_TYPE(UserType));
assert_param(IS_OB_USER_CONFIG(UserType, UserConfig));
optr = FLASH->OPTR;
optr &= ~(UserType | 0xff);
FLASH->OPTR = (optr | UserConfig | 0xAA);
}
/**
* @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)
{
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);
}
if ((pOBInit->OptionType & OPTIONBYTE_USER) != 0x00U)
{
FLASH_OB_OptrConfig(pOBInit->USERType, pOBInit->USERConfig);
}
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 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 pBOOTInit pointer to an FLASH_OBBootProgramInitTypeDef structure that
* contains the configuration information for the programming.
*
* @retval HAL_StatusTypeDef HAL Status
*/
HAL_StatusTypeDef HAL_FLASH_OBBOOTProgram(FLASH_OBBootProgramInitTypeDef *pBOOTInit)
{
HAL_StatusTypeDef status = HAL_ERROR;
/* Process Locked */
__HAL_LOCK(&pFlash);
/* Config flash timming */
__HAL_FLASH_TIMMING_SEQUENCE_CONFIG();
/* Check the parameters */
assert_param(IS_OB_BOOTTYPE(pBOOTInit->BOOTType));
assert_param(IS_OB_BOOTSIZE(pBOOTInit->BOOTSize));
MODIFY_REG(FLASH->BTCR, FLASH_BTCR_NBOOT1 | FLASH_BTCR_BOOT0 | FLASH_BTCR_BOOT_SIZE ,pBOOTInit->BOOTType | pBOOTInit->BOOTSize );
/* 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 Boot configuration
* @param pBOOTInit pointer to an FLASH_OBInitStruct structure that
* contains the configuration information for the programming.
*
* @retval None
*/
void HAL_FLASH_OBBOOTGetConfig(FLASH_OBBootProgramInitTypeDef *pBOOTInit)
{
pBOOTInit->BOOTType= READ_BIT(FLASH->BTCR,FLASH_BTCR_BOOT0 | FLASH_BTCR_NBOOT1 ) ;
pBOOTInit->BOOTSize= READ_BIT(FLASH->BTCR,FLASH_BTCR_BOOT_SIZE);
}
/**
* @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 USER*/
pOBInit->USERType = OB_USER_ALL;
pOBInit->USERConfig = (FLASH->OPTR)&(FLASH_OPTR_IWDG_SW | FLASH_OPTR_IWDG_STOP | \
FLASH_OPTR_NRST_MODE | FLASH_OPTR_BOR_EN | \
FLASH_OPTR_BOR_LEV | FLASH_OPTR_SWD_MODE);
}
/**
* @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****/

View File

@@ -0,0 +1,532 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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 (0x00010000U)
/* 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..C) to select the GPIO peripheral for PY32F002B 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..C) to select the GPIO peripheral for PY32F002B 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..C) to select the GPIO peripheral for PY32F002B 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..C) to select the GPIO peripheral for PY32F002B 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..C) to select the GPIO peripheral for PY32F002B 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..C) to select the GPIO peripheral for PY32F002B 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****/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,242 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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****/

View File

@@ -0,0 +1,954 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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;
}
#if defined(LPTIM_CR_CNTSTRT)
/**
* @brief Start the LPTIM in Set continue 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_SetContinue_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 continue mode */
__HAL_LPTIM_START_CONTINUE(hlptim);
/* Change the TIM state*/
hlptim->State= HAL_LPTIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief Stop the LPTIM Set continue mode.
* @param hlptim LPTIM handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_LPTIM_SetContinue_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 continue 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_SetContinue_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 continue mode */
__HAL_LPTIM_START_CONTINUE(hlptim);
/* Change the TIM state*/
hlptim->State= HAL_LPTIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief Stop the LPTIM Set continue mode in interrupt mode.
* @param hlptim LPTIM handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_LPTIM_SetContinue_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;
}
#endif
/**
* @}
*/
/** @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);
}
/**
* @brief Counter synchronous reset.
* @param lptim pointer to a LPTIM_HandleTypeDef structure that contains
* the configuration information for LPTIM module.
* @retval None
*/
uint32_t HAL_LPTIM_ResetCounter(LPTIM_HandleTypeDef *hlptim)
{
/* Check the parameters */
assert_param(IS_LPTIM_INSTANCE(hlptim->Instance));
if(READ_BIT(hlptim->Instance->CR, LPTIM_CR_COUNTRST) == 0)
{
SET_BIT(hlptim->Instance->CR, LPTIM_CR_COUNTRST);
}
else
{
return HAL_ERROR;
}
return HAL_OK;
}
/**
* @}
*/
/** @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 */
}
}
/* Autoreload Update completed interrupt */
if(__HAL_LPTIM_GET_FLAG(hlptim, LPTIM_FLAG_ARROK) != RESET)
{
if(__HAL_LPTIM_GET_IT_SOURCE(hlptim, LPTIM_IT_ARROK) != RESET)
{
/* Clear Autoreload Update completed flag */
__HAL_LPTIM_CLEAR_FLAG(hlptim, LPTIM_FLAG_ARROK);
/* Autoreload Update completed Callback */
#if (USE_HAL_LPTIM_REGISTER_CALLBACKS == 1)
hlptim->HAL_LPTIM_AutoReloadUpdateCompletedCallback(hlptim);
#else
HAL_LPTIM_AutoReloadUpdateCompletedCallback(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
*/
}
/**
* @brief Autoreload Update completed callback in non-blocking mode.
* @param hlptim LPTIM handle
* @retval None
*/
__weak void HAL_LPTIM_AutoReloadUpdateCompletedCallback(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_AutoReloadUpdateCompletedCallback 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****/

View File

@@ -0,0 +1,400 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_HAL_Driver
* @{
*/
/** @addtogroup PWR
* @{
*/
#ifdef HAL_PWR_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* 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 Configure LPR voltage,sram retention voltage,and wakeup correlation
timing in Sto mode.
* @param sStopModeConfig pointer to a PWR_StopModeConfigTypeDef structure that
contains the Stop mode configuration information.
* @retval HAL_OK
*/
HAL_StatusTypeDef HAL_PWR_ConfigStopMode(PWR_StopModeConfigTypeDef *sStopModeConfig)
{
/* Check the parameters */
assert_param(IS_PWR_WAKEUP_HSIEN_TIMING(sStopModeConfig->WakeUpHsiEnableTime));
#if defined(PWR_DEEPSTOP_SUPPORT)
assert_param(IS_PWR_SRAM_RETENTION_VOLT(sStopModeConfig->SramRetentionVoltDlp));
#endif /* PWR_DEEPSTOP_SUPPORT */
assert_param(IS_PWR_SRAM_RETENTION_VOLT(sStopModeConfig->SramRetentionVolt));
assert_param(IS_PWR_WAKEUP_FLASH_DELAY(sStopModeConfig->FlashDelay));
/* Set the STOP mode and STOP wake-up timing related configurations */
#if defined(PWR_DEEPSTOP_SUPPORT)
MODIFY_REG(PWR->CR1, PWR_CR1_SRAM_RETV_DLP, (sStopModeConfig->SramRetentionVoltDlp << PWR_CR1_SRAM_RETV_DLP_Pos));
#endif /* PWR_DEEPSTOP_SUPPORT */
MODIFY_REG(PWR->CR1, (PWR_CR1_HSION_CTRL | PWR_CR1_SRAM_RETV | PWR_CR1_FLS_SLPTIME),
(sStopModeConfig->WakeUpHsiEnableTime) | \
(sStopModeConfig->SramRetentionVolt << PWR_CR1_SRAM_RETV_Pos) | \
(sStopModeConfig->FlashDelay));
return HAL_OK;
}
/**
* @brief Configure the bias current load source and bias current values.
* @param sBIASConfig pointer to a PWR_BIASConfigTypeDef structure that
contains the bias current configuration information.
* @retval HAL_OK
*/
HAL_StatusTypeDef HAL_PWR_ConfigBIAS(PWR_BIASConfigTypeDef *sBIASConfig)
{
/* Check the parameters */
assert_param(IS_BIAS_CURRENTS_SOURCE(sBIASConfig->BiasCurrentSource));
if(((sBIASConfig->BiasCurrentSource) & PWR_BIAS_CURRENTS_FROM_BIAS_CR) == PWR_BIAS_CURRENTS_FROM_BIAS_CR)
{
/* Set the bias currents load source and bias currents value*/
MODIFY_REG(PWR->CR1, (PWR_CR1_BIAS_CR_SEL) | (PWR_CR1_BIAS_CR), (sBIASConfig->BiasCurrentSource) | \
(sBIASConfig->BiasCurrentValue));
}
else
{
/* Set the bias currents load source */
MODIFY_REG(PWR->CR1, PWR_CR1_BIAS_CR_SEL, (sBIASConfig->BiasCurrentSource));
}
return HAL_OK;
}
/**
* @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
* @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)
* @arg @ref PWR_DEEPLOWPOWERREGULATOR_ON Stop 2 mode (deep low power regulator ON)
* @param STOPEntry Specifies Stop 0 、Stop 1 or Stop 2 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 、Stop 1 or Stop 2 mode with WFI
* instruction.
* @arg @ref PWR_STOPENTRY_WFE Enter Stop 0 、Stop 1 or Stop 2 mode with WFE
* instruction.
* @note Depending on devices and packages, some Stop modes may not be available.
* Refer to device datasheet for Stop modes availability.
* @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));
/* Config Regulator */
MODIFY_REG(PWR->CR1, PWR_CR1_LPR, Regulator);
/* 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));
}
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_PWR_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,1103 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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 HSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
#define LSI_TIMEOUT_VALUE (2U) /* 2 ms (minimum Tick + 1) */
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/** @defgroup RCC_Private_Variables RCC Private Variables
* @{
*/
/**
* @}
*/
/* Private function prototypes -----------------------------------------------*/
/* 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, 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 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;
/* 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 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;
/* 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 (temp_sysclksrc == RCC_CFGR_SWS_HSE)
{
if (RCC_OscInitStruct->HSEState == RCC_HSE_BYPASS_DISABLE)
{
return HAL_ERROR;
}
}
else
{
/* Set the new HSE configuration ---------------------------------------*/
__HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
}
}
/*----------------------------- 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 */
temp_sysclksrc = __HAL_RCC_GET_SYSCLK_SOURCE();
if (temp_sysclksrc == RCC_CFGR_SWS_HSISYS)
{
/* When HSI is used as system 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_HSISYS)
{
/* 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
{
/* Adjusts the Internal Low Speed oscillator (LSI) calibration value.*/
__HAL_RCC_LSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->LSICalibrationValue);
/* 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;
}
}
if (temp_sysclksrc == RCC_CFGR_SWS_LSI)
{
/* Update the SystemCoreClock global variable with LSI 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 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;
}
}
/* Adjusts the Internal Low Speed oscillator (LSI) calibration value.*/
__HAL_RCC_LSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->LSICalibrationValue);
}
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;
}
}
}
}
}
/*------------------------------ LSE Configuration -------------------------*/
if (((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE)
{
/* 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
{
/* Set driver factor of the LSE*/
if (RCC_OscInitStruct->LSEState != RCC_LSE_OFF)
{
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;
}
}
}
}
}
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).
* 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 Enable */
if (READ_BIT(RCC->CR, RCC_CR_HSEEN) == 0U)
{
return HAL_ERROR;
}
}
/* HSI is selected as System Clock Source */
else if (RCC_ClkInitStruct->SYSCLKSource == RCC_SYSCLKSOURCE_HSISYS)
{
/* Check the HSI ready flag */
if (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == 0U)
{
return HAL_ERROR;
}
}
/* 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;
}
}
/* 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.
* @param RCC_MCOx specifies the output direction for the clock source.
* @arg @ref RCC_MCO1 Clock source to output on MCO1 pin(PA07).
* @arg @ref RCC_MCO2 Clock source to output on MCO2 pin(PB01).
* @param RCC_MCOSource specifies the clock source to output.
* This parameter can be one of the following values:
* @arg @ref RCC_MCOSOURCE_NOCLOCK MCO output disabled, no clock on MCO
* @arg @ref RCC_MCOSOURCE_SYSCLK system clock selected as MCO source
* @arg @ref RCC_MCOSOURCE_HSI HSI clock selected as MCO source
* @arg @ref RCC_MCOSOURCE_HSE HSE clock selected as MCO sourcee
* @arg @ref RCC_MCOSOURCE_LSI LSI clock selected as MCO source
* @arg @ref RCC_MCOSOURCE_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 PB01 as the clock output */
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_1;
GPIO_InitStruct.Alternate = GPIO_AF4_MCO;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
break;
case RCC_MCO1 : /* Configure PA07 as the clock output */
default :
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Alternate = GPIO_AF4_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 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 py32f002b_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 py32f002b_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 py32f002b_hal_conf.h file (default value
* 32768 Hz).
* @note (****) LSI_VALUE is a constant defined in py32f002b_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;
#if defined(RCC_HSI48M_SUPPORT)
const uint32_t hsiValue[8] = {0U, 0U, 0U, 0U, 24000000U, 48000000U, 0U, 0U};
#else
const uint32_t hsiValue[8] = {0U, 0U, 0U, 0U, 24000000U, 0U, 0U, 0U};
#endif
uint32_t hsiIndex;
if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSISYS)
{
/* 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;
sysclockfreq = (hsiValue[hsiIndex] / hsidiv);
}
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE)
{
/* HSE used as system clock source */
sysclockfreq = HSE_VALUE;
}
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSE)
{
/* LSE used as system clock source */
sysclockfreq = LSE_VALUE;
}
else if (__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_LSI)
{
/* LSI used as system clock source */
if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_32768Hz)
{
sysclockfreq = 32768U;
}
else if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_38400Hz)
{
sysclockfreq = 38400U;
}
else
{
sysclockfreq = 0U;
}
}
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 ---------------*/
RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | \
RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI;
/* Get the HSE configuration -----------------------------------------------*/
if ((RCC->CR & RCC_CR_HSEEN) == RCC_CR_HSEEN)
{
RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS_ENABLE;
}
else
{
RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS_DISABLE;
}
/* 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;
}
RCC_OscInitStruct->LSICalibrationValue = ((RCC->ICSCR & RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos);
/* 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);
}
/**
* @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 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) ;
}
/**
* @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 */
RCC->CICR = (itflag & RCC_CIFR_LSECSSF);
/* Check RCC LSECSSF interrupt flag */
if ((itflag & RCC_CIFR_LSECSSF) != 0x00u)
{
/* RCC Clock Security System interrupt user callback */
HAL_RCC_LSECSSCallback();
}
}
/**
* @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****/

View File

@@ -0,0 +1,363 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_HAL_Driver
* @{
*/
/** @defgroup RCCEx RCCEx
* @brief RCC Extended HAL module driver
* @{
*/
#ifdef HAL_RCC_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/* 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_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)
{
/* Check the parameters */
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
#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: COMP1, COMP2, 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------------*/
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_COMP1 | RCC_PERIPHCLK_COMP2 | \
RCC_PERIPHCLK_LPTIM;
#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 */
}
/**
* @brief Return the peripheral clock frequency.
* @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_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;
/* Check the parameters */
assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
switch (PeriphClk)
{
#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();
}
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))
{
if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_32768Hz)
{
frequency = 32768U;
}
else if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_38400Hz)
{
frequency = 38400U;
}
else
{
frequency = 0U;
}
}
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 */
}
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();
}
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))
{
if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_32768Hz)
{
frequency = 32768U;
}
else if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_38400Hz)
{
frequency = 38400U;
}
else
{
frequency = 0U;
}
}
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 */
}
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))
{
if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_32768Hz)
{
frequency = 32768U;
}
else if ((READ_BIT(RCC->ICSCR, RCC_ICSCR_LSI_TRIM) >> RCC_ICSCR_LSI_TRIM_Pos) == RCC_LSICALIBRATION_38400Hz)
{
frequency = 38400U;
}
else
{
frequency = 0U;
}
}
else if ((HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)) && (srcclk == RCC_LPTIMCLKSOURCE_LSE))
{
frequency = LSE_VALUE;
}
/* Clock not enabled for LPTIM1 */
else
{
/* Nothing to do as frequency already initialized to 0U */
}
break;
#endif /* RCC_CCIPR_LPTIM1SEL */
default:
break;
}
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
* @{
*/
/**
* @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)
{
/* Check the parameters */
assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
}
/**
* @brief Disable the Low Speed clock output.
* @retval None
*/
void HAL_RCCEx_DisableLSCO(void)
{
CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_RCC_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,2480 @@
/**
******************************************************************************
* @file py32f002b_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
(#) 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.
[..]
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()
[..]
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 | Transfer mode |---------------------|----------------------|----------------------|
| | | Master | Slave | Master | Slave | Master | Slave |
|==============================================================================================|
| TX | Polling | Fpclk/4 | Fpclk/8 | NA | NA | NA | NA |
| / |----------------|----------|----------|-----------|----------|-----------|----------|
| RX | Interrupt | Fpclk/4 | Fpclk/16 | 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 |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | Fpclk/8 | Fpclk/2 | NA | NA | Fpclk/8 | Fpclk/8 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
| T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/16 | Fpclk/8 |
| X |----------------|----------|----------|-----------|----------|-----------|----------|
+----------------------------------------------------------------------------------------------+
DataSize = SPI_DATASIZE_16BIT:
+----------------------------------------------------------------------------------------------+
| | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
| Process | Transfer mode |---------------------|----------------------|----------------------|
| | | Master | Slave | Master | Slave | Master | Slave |
|==============================================================================================|
| TX | Polling | Fpclk/4 | Fpclk/8 | NA | NA | NA | NA |
| / |----------------|----------|----------|-----------|----------|-----------|----------|
| RX | Interrupt | Fpclk/4 | Fpclk/16 | 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 |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | Fpclk/8 | Fpclk/2 | NA | NA | Fpclk/8 | Fpclk/8 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
| T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/16 | Fpclk/8 |
| X |----------------|----------|----------|-----------|----------|-----------|----------|
+----------------------------------------------------------------------------------------------+
@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).
@note
(#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT()
(#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT()
(#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT()
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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
* @{
*/
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, 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)
{
/* 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));
assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
if (hspi->Init.Mode == SPI_MODE_MASTER)
{
assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
}
else
{
/* Baudrate prescaler not use in Motoraola Slave mode. force to default value */
hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
}
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);
/*----------------------- 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 & (SPI_CR1_MSTR | SPI_CR1_SSI)) |
(hspi->Init.Direction & (SPI_CR1_RXONLY | SPI_CR1_BIDIMODE)) |
(hspi->Init.CLKPolarity & SPI_CR1_CPOL) |
(hspi->Init.CLKPhase & SPI_CR1_CPHA) |
(hspi->Init.NSS & SPI_CR1_SSM) |
(hspi->Init.BaudRatePrescaler & SPI_CR1_BR_Msk) |
(hspi->Init.DataSize & SPI_CR1_DFF_Msk) |
(hspi->Init.FirstBit & SPI_CR1_LSBFIRST)));
/* Configure : NSS management */
WRITE_REG(hspi->Instance->CR2, ((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE));
#if defined(SPI_I2SCFGR_I2SMOD)
/* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
#endif /* SPI_I2SCFGR_I2SMOD */
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
, These APIs return the HAL status.
The end of the data processing will be indicated through the
dedicated SPI IRQ when using Interrupt 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)
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;
}
/* 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)
{
/* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
__HAL_SPI_DISABLE(hspi);
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.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;
}
/* 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;
/* Configure communication direction: 1Line */
if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
{
/* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
__HAL_SPI_DISABLE(hspi);
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;
}
/* 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;
/* 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;
}
/* 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)
{
/* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
__HAL_SPI_DISABLE(hspi);
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;
}
/* 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)
{
hspi->RxISR = SPI_RxISR_16BIT;
}
else
{
hspi->RxISR = SPI_RxISR_8BIT;
}
/* Configure communication direction : 1Line */
if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
{
/* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */
__HAL_SPI_DISABLE(hspi);
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;
}
/* 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;
}
/* 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;
}
/**
* @brief Abort ongoing transfer (blocking mode).
* @param hspi SPI handle.
* This procedure performs following operations :
* - Disable SPI Interrupts (depending of transfer direction)
* - 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_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;
}
/* 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 mode.
* This procedure performs following operations :
* - Disable SPI Interrupts (depending of transfer direction)
* - 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_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 (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;
/* 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;
}
/**
* @brief Handle SPI interrupt request.
* @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);
}
/* SPI Frame error interrupt occurred ------------------------------------*/
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;
/* 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;
}
}
/**
* @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
* @{
*/
/**
* @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 8 Bit mode */
*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 8 Bit mode */
*(__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 the SPI */
/* 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 the SPI */
/* 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 management */
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****/

View File

@@ -0,0 +1,4969 @@
/**
******************************************************************************
* @file py32f002b_hal_tim.c
* @author MCU Application Team
* @brief TIM HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Timer (TIM) peripheral:
* + TIM Time Base Initialization
* + TIM Time Base Start
* + TIM Time Base Start Interruption
* + TIM Time Base Start DMA
* + TIM Output Compare/PWM Initialization
* + TIM Output Compare/PWM Channel Configuration
* + TIM Output Compare/PWM Start
* + TIM Output Compare/PWM Start Interruption
* + TIM Output Compare/PWM Start DMA
* + TIM Input Capture Initialization
* + TIM Input Capture Channel Configuration
* + TIM Input Capture Start
* + TIM Input Capture Start Interruption
* + TIM Input Capture Start DMA
* + TIM One Pulse Initialization
* + TIM One Pulse Channel Configuration
* + TIM One Pulse Start
* + TIM Encoder Interface Initialization
* + TIM Encoder Interface Start
* + TIM Encoder Interface Start Interruption
* + TIM Encoder Interface Start DMA
* + Commutation Event configuration with Interruption and DMA
* + TIM OCRef clear configuration
* + TIM External Clock configuration
@verbatim
==============================================================================
##### TIMER Generic features #####
==============================================================================
[..] The Timer features include:
(#) 16-bit up, down, up/down auto-reload counter.
(#) 16-bit programmable prescaler allowing dividing (also on the fly) the
counter clock frequency either by any factor between 1 and 65536.
(#) Up to 4 independent channels for:
(++) Input Capture
(++) 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.
(#) Supports incremental encoder for positioning purposes
##### How to use this driver #####
==============================================================================
[..]
(#) Initialize the TIM low level resources by implementing the following functions
depending on the selected feature:
(++) Time Base : HAL_TIM_Base_MspInit()
(++) Input Capture : HAL_TIM_IC_MspInit()
(++) Output Compare : HAL_TIM_OC_MspInit()
(++) PWM generation : HAL_TIM_PWM_MspInit()
(++) One-pulse mode output : HAL_TIM_OnePulse_MspInit()
(++) Encoder mode output : HAL_TIM_Encoder_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_TIM_Base_Init: to use the Timer to generate a simple time base
(++) HAL_TIM_OC_Init and HAL_TIM_OC_ConfigChannel: to use the Timer to generate an
Output Compare signal.
(++) HAL_TIM_PWM_Init and HAL_TIM_PWM_ConfigChannel: to use the Timer to generate a
PWM signal.
(++) HAL_TIM_IC_Init and HAL_TIM_IC_ConfigChannel: to use the Timer to measure an
external signal.
(++) HAL_TIM_OnePulse_Init and HAL_TIM_OnePulse_ConfigChannel: to use the Timer
in One Pulse Mode.
(++) HAL_TIM_Encoder_Init: to use the Timer Encoder Interface.
(#) Activate the TIM peripheral using one of the start functions depending from the feature used:
(++) Time Base : HAL_TIM_Base_Start(), HAL_TIM_Base_Start_DMA(), HAL_TIM_Base_Start_IT()
(++) Input Capture : HAL_TIM_IC_Start(), HAL_TIM_IC_Start_DMA(), HAL_TIM_IC_Start_IT()
(++) Output Compare : HAL_TIM_OC_Start(), HAL_TIM_OC_Start_DMA(), HAL_TIM_OC_Start_IT()
(++) PWM generation : HAL_TIM_PWM_Start(), HAL_TIM_PWM_Start_DMA(), HAL_TIM_PWM_Start_IT()
(++) One-pulse mode output : HAL_TIM_OnePulse_Start(), HAL_TIM_OnePulse_Start_IT()
(++) Encoder mode output : HAL_TIM_Encoder_Start(), HAL_TIM_Encoder_Start_DMA(), HAL_TIM_Encoder_Start_IT().
(#) The DMA Burst is managed with the two following functions:
HAL_TIM_DMABurst_WriteStart()
HAL_TIM_DMABurst_ReadStart()
*** Callback registration ***
=============================================
[..]
The compilation define USE_HAL_TIM_REGISTER_CALLBACKS when set to 1
allows the user to configure dynamically the driver callbacks.
[..]
Use Function @ref HAL_TIM_RegisterCallback() to register a callback.
@ref HAL_TIM_RegisterCallback() takes as parameters the HAL peripheral handle,
the Callback ID and a pointer to the user callback function.
[..]
Use function @ref HAL_TIM_UnRegisterCallback() to reset a callback to the default
weak function.
@ref HAL_TIM_UnRegisterCallback takes as parameters the HAL peripheral handle,
and the Callback ID.
[..]
These functions allow to register/unregister following callbacks:
(+) Base_MspInitCallback : TIM Base Msp Init Callback.
(+) Base_MspDeInitCallback : TIM Base Msp DeInit Callback.
(+) IC_MspInitCallback : TIM IC Msp Init Callback.
(+) IC_MspDeInitCallback : TIM IC Msp DeInit Callback.
(+) OC_MspInitCallback : TIM OC Msp Init Callback.
(+) OC_MspDeInitCallback : TIM OC Msp DeInit Callback.
(+) PWM_MspInitCallback : TIM PWM Msp Init Callback.
(+) PWM_MspDeInitCallback : TIM PWM Msp DeInit Callback.
(+) OnePulse_MspInitCallback : TIM One Pulse Msp Init Callback.
(+) OnePulse_MspDeInitCallback : TIM One Pulse Msp DeInit Callback.
(+) Encoder_MspInitCallback : TIM Encoder Msp Init Callback.
(+) Encoder_MspDeInitCallback : TIM Encoder Msp DeInit Callback.
(+) HallSensor_MspInitCallback : TIM Hall Sensor Msp Init Callback.
(+) HallSensor_MspDeInitCallback : TIM Hall Sensor Msp DeInit Callback.
(+) PeriodElapsedCallback : TIM Period Elapsed Callback.
(+) PeriodElapsedHalfCpltCallback : TIM Period Elapsed half complete Callback.
(+) TriggerCallback : TIM Trigger Callback.
(+) TriggerHalfCpltCallback : TIM Trigger half complete Callback.
(+) IC_CaptureCallback : TIM Input Capture Callback.
(+) IC_CaptureHalfCpltCallback : TIM Input Capture half complete Callback.
(+) OC_DelayElapsedCallback : TIM Output Compare Delay Elapsed Callback.
(+) PWM_PulseFinishedCallback : TIM PWM Pulse Finished Callback.
(+) PWM_PulseFinishedHalfCpltCallback : TIM PWM Pulse Finished half complete Callback.
(+) ErrorCallback : TIM Error Callback.
(+) CommutationCallback : TIM Commutation Callback.
(+) CommutationHalfCpltCallback : TIM Commutation half complete Callback.
(+) BreakCallback : TIM Break Callback.
[..]
By default, after the Init and when the state is HAL_TIM_STATE_RESET
all interrupt callbacks are set to the corresponding weak functions:
examples @ref HAL_TIM_TriggerCallback(), @ref HAL_TIM_ErrorCallback().
[..]
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_TIM_STATE_READY state only.
Exception done MspInit / MspDeInit that can be registered / unregistered
in HAL_TIM_STATE_READY or HAL_TIM_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_TIM_RegisterCallback() before calling DeInit or Init function.
[..]
When The compilation define USE_HAL_TIM_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_HAL_Driver
* @{
*/
/** @defgroup TIM TIM
* @brief TIM HAL module driver
* @{
*/
#ifdef HAL_TIM_MODULE_ENABLED
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/** @addtogroup TIM_Private_Functions
* @{
*/
static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config);
static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter);
static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter);
static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter);
static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter);
static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource);
#if (defined(DMA) || defined(DMA1))
static void TIM_DMAPeriodElapsedCplt(DMA_HandleTypeDef *hdma);
static void TIM_DMAPeriodElapsedHalfCplt(DMA_HandleTypeDef *hdma);
static void TIM_DMATriggerCplt(DMA_HandleTypeDef *hdma);
static void TIM_DMATriggerHalfCplt(DMA_HandleTypeDef *hdma);
#endif
static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
TIM_SlaveConfigTypeDef *sSlaveConfig);
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup TIM_Exported_Functions TIM Exported Functions
* @{
*/
/** @defgroup TIM_Exported_Functions_Group1 TIM Time Base functions
* @brief Time Base functions
*
@verbatim
==============================================================================
##### Time Base functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM base.
(+) De-initialize the TIM base.
(+) Start the Time Base.
(+) Stop the Time Base.
(+) Start the Time Base and enable interrupt.
(+) Stop the Time Base and disable interrupt.
(+) Start the Time Base and enable DMA transfer.
(+) Stop the Time Base and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM Time base Unit according to the specified
* parameters in the TIM_HandleTypeDef and initialize the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_Base_DeInit() before HAL_TIM_Base_Init()
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_TIM_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));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->Base_MspInitCallback == NULL)
{
htim->Base_MspInitCallback = HAL_TIM_Base_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->Base_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC */
HAL_TIM_Base_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Set the Time Base configuration */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM Base peripheral
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_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->Base_MspDeInitCallback == NULL)
{
htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit;
}
/* DeInit the low level hardware */
htim->Base_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC */
HAL_TIM_Base_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 Base MSP.
* @param htim TIM Base handle
* @retval None
*/
__weak void HAL_TIM_Base_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_TIM_Base_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM Base MSP.
* @param htim TIM Base handle
* @retval None
*/
__weak void HAL_TIM_Base_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_TIM_Base_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the TIM Base generation.
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Start(TIM_HandleTypeDef *htim)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* 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);
}
/* Change the TIM state*/
htim->State = HAL_TIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief Stops the TIM Base generation.
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Stop(TIM_HandleTypeDef *htim)
{
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Change the TIM state*/
htim->State = HAL_TIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @brief Starts the TIM Base generation in interrupt mode.
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Start_IT(TIM_HandleTypeDef *htim)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Enable the TIM Update interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_UPDATE);
/* 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 Base generation in interrupt mode.
* @param htim TIM Base handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Base_Stop_IT(TIM_HandleTypeDef *htim)
{
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
/* Disable the TIM Update interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_UPDATE);
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/** @defgroup TIM_Exported_Functions_Group2 TIM Output Compare functions
* @brief TIM Output Compare functions
*
@verbatim
==============================================================================
##### TIM Output Compare functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM Output Compare.
(+) De-initialize the TIM Output Compare.
(+) Start the TIM Output Compare.
(+) Stop the TIM Output Compare.
(+) Start the TIM Output Compare and enable interrupt.
(+) Stop the TIM Output Compare and disable interrupt.
(+) Start the TIM Output Compare and enable DMA transfer.
(+) Stop the TIM Output Compare and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM Output Compare according to the specified
* parameters in the TIM_HandleTypeDef and initializes the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_OC_DeInit() before HAL_TIM_OC_Init()
* @param htim TIM Output Compare handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_Init(TIM_HandleTypeDef *htim)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_TIM_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));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->OC_MspInitCallback == NULL)
{
htim->OC_MspInitCallback = HAL_TIM_OC_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->OC_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
HAL_TIM_OC_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Init the base time for the Output Compare */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM peripheral
* @param htim TIM Output Compare handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_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->OC_MspDeInitCallback == NULL)
{
htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit;
}
/* DeInit the low level hardware */
htim->OC_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
HAL_TIM_OC_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 Output Compare MSP.
* @param htim TIM Output Compare handle
* @retval None
*/
__weak void HAL_TIM_OC_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_TIM_OC_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM Output Compare MSP.
* @param htim TIM Output Compare handle
* @retval None
*/
__weak void HAL_TIM_OC_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_TIM_OC_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the TIM Output Compare signal generation.
* @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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Enable the Output compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Disable the Output compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Enable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Enable the Output compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Disable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Disable the Output compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Disable the Main Output */
__HAL_TIM_MOE_DISABLE(htim);
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/** @defgroup TIM_Exported_Functions_Group3 TIM PWM functions
* @brief TIM PWM functions
*
@verbatim
==============================================================================
##### TIM PWM functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM PWM.
(+) De-initialize the TIM PWM.
(+) Start the TIM PWM.
(+) Stop the TIM PWM.
(+) Start the TIM PWM and enable interrupt.
(+) Stop the TIM PWM and disable interrupt.
(+) Start the TIM PWM and enable DMA transfer.
(+) Stop the TIM PWM and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM PWM Time Base according to the specified
* parameters in the TIM_HandleTypeDef and initializes the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_PWM_DeInit() before HAL_TIM_PWM_Init()
* @param htim TIM PWM handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Init(TIM_HandleTypeDef *htim)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_TIM_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));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->PWM_MspInitCallback == NULL)
{
htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->PWM_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
HAL_TIM_PWM_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Init the base time for the PWM */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM peripheral
* @param htim TIM PWM handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_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->PWM_MspDeInitCallback == NULL)
{
htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit;
}
/* DeInit the low level hardware */
htim->PWM_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
HAL_TIM_PWM_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 PWM MSP.
* @param htim TIM PWM handle
* @retval None
*/
__weak void HAL_TIM_PWM_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_TIM_PWM_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM PWM MSP.
* @param htim TIM PWM handle
* @retval None
*/
__weak void HAL_TIM_PWM_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_TIM_PWM_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the PWM signal generation.
* @param htim TIM handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Enable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @param htim TIM PWM handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Disable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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;
}
/**
* @brief Starts the PWM signal generation in interrupt mode.
* @param htim TIM PWM 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Enable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Enable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @param htim TIM PWM handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Disable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Disable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Disable the Main Output */
__HAL_TIM_MOE_DISABLE(htim);
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group4 TIM Input Capture functions
* @brief TIM Input Capture functions
*
@verbatim
==============================================================================
##### TIM Input Capture functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM Input Capture.
(+) De-initialize the TIM Input Capture.
(+) Start the TIM Input Capture.
(+) Stop the TIM Input Capture.
(+) Start the TIM Input Capture and enable interrupt.
(+) Stop the TIM Input Capture and disable interrupt.
(+) Start the TIM Input Capture and enable DMA transfer.
(+) Stop the TIM Input Capture and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM Input Capture Time base according to the specified
* parameters in the TIM_HandleTypeDef and initializes the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_IC_DeInit() before HAL_TIM_IC_Init()
* @param htim TIM Input Capture handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_Init(TIM_HandleTypeDef *htim)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_TIM_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));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->IC_MspInitCallback == NULL)
{
htim->IC_MspInitCallback = HAL_TIM_IC_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->IC_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
HAL_TIM_IC_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Init the base time for the input capture */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM peripheral
* @param htim TIM Input Capture handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_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->IC_MspDeInitCallback == NULL)
{
htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit;
}
/* DeInit the low level hardware */
htim->IC_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC and DMA */
HAL_TIM_IC_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 Input Capture MSP.
* @param htim TIM Input Capture handle
* @retval None
*/
__weak void HAL_TIM_IC_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_TIM_IC_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM Input Capture MSP.
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_IC_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_TIM_IC_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the TIM Input Capture measurement.
* @param htim TIM Input Capture handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Enable the Input Capture channel */
TIM_CCxChannelCmd(htim->Instance, Channel, 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 Input Capture measurement.
* @param htim TIM Input Capture handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
/* Disable the Input Capture channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @brief Starts the TIM Input Capture measurement in interrupt mode.
* @param htim TIM Input Capture handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpsmcr;
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Enable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Enable the Input Capture channel */
TIM_CCxChannelCmd(htim->Instance, Channel, 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 Input Capture measurement in interrupt mode.
* @param htim TIM Input Capture handle
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_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;
}
case TIM_CHANNEL_4:
{
/* Disable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
break;
}
default:
break;
}
/* Disable the Input Capture channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group5 TIM One Pulse functions
* @brief TIM One Pulse functions
*
@verbatim
==============================================================================
##### TIM One Pulse functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM One Pulse.
(+) De-initialize the TIM One Pulse.
(+) Start the TIM One Pulse.
(+) Stop the TIM One Pulse.
(+) Start the TIM One Pulse and enable interrupt.
(+) Stop the TIM One Pulse and disable interrupt.
(+) Start the TIM One Pulse and enable DMA transfer.
(+) Stop the TIM One Pulse and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM One Pulse Time Base according to the specified
* parameters in the TIM_HandleTypeDef and initializes the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_OnePulse_DeInit() before HAL_TIM_OnePulse_Init()
* @param htim TIM One Pulse handle
* @param OnePulseMode Select the One pulse mode.
* This parameter can be one of the following values:
* @arg TIM_OPMODE_SINGLE: Only one pulse will be generated.
* @arg TIM_OPMODE_REPETITIVE: Repetitive pulses will be generated.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OnePulse_Init(TIM_HandleTypeDef *htim, uint32_t OnePulseMode)
{
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_TIM_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_OPM_MODE(OnePulseMode));
assert_param(IS_TIM_AUTORELOAD_PRELOAD(htim->Init.AutoReloadPreload));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->OnePulse_MspInitCallback == NULL)
{
htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->OnePulse_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
HAL_TIM_OnePulse_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Configure the Time base in the One Pulse Mode */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Reset the OPM Bit */
htim->Instance->CR1 &= ~TIM_CR1_OPM;
/* Configure the OPM Mode */
htim->Instance->CR1 |= OnePulseMode;
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM One Pulse
* @param htim TIM One Pulse handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OnePulse_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->OnePulse_MspDeInitCallback == NULL)
{
htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit;
}
/* DeInit the low level hardware */
htim->OnePulse_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC */
HAL_TIM_OnePulse_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 One Pulse MSP.
* @param htim TIM One Pulse handle
* @retval None
*/
__weak void HAL_TIM_OnePulse_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_TIM_OnePulse_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM One Pulse MSP.
* @param htim TIM One Pulse handle
* @retval None
*/
__weak void HAL_TIM_OnePulse_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_TIM_OnePulse_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the TIM One Pulse signal generation.
* @param htim TIM One Pulse handle
* @param OutputChannel TIM Channels 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_TIM_OnePulse_Start(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(OutputChannel);
/* Enable the Capture compare and the Input Capture channels
(in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
No need to enable the counter, it's enabled automatically by hardware
(the counter starts in response to a stimulus and generate a pulse */
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Enable the main output */
__HAL_TIM_MOE_ENABLE(htim);
}
/* Return function status */
return HAL_OK;
}
/**
* @brief Stops the TIM One Pulse signal generation.
* @param htim TIM One Pulse handle
* @param OutputChannel TIM Channels to be disable
* 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_TIM_OnePulse_Stop(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(OutputChannel);
/* Disable the Capture compare and the Input Capture channels
(in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @param htim TIM One Pulse handle
* @param OutputChannel TIM Channels 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_TIM_OnePulse_Start_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(OutputChannel);
/* Enable the Capture compare and the Input Capture channels
(in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be enabled together
No need to enable the counter, it's enabled automatically by hardware
(the counter starts in response to a stimulus and generate a pulse */
/* 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);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* 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.
* @param htim TIM One Pulse handle
* @param OutputChannel TIM Channels 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_TIM_OnePulse_Stop_IT(TIM_HandleTypeDef *htim, uint32_t OutputChannel)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(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 Capture compare and the Input Capture channels
(in the OPM Mode the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2)
if TIM_CHANNEL_1 is used as output, the TIM_CHANNEL_2 will be used as input and
if TIM_CHANNEL_1 is used as input, the TIM_CHANNEL_2 will be used as output
in all combinations, the TIM_CHANNEL_1 and TIM_CHANNEL_2 should be disabled together */
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
if (IS_TIM_BREAK_INSTANCE(htim->Instance) != RESET)
{
/* Disable the Main Output */
__HAL_TIM_MOE_DISABLE(htim);
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group6 TIM Encoder functions
* @brief TIM Encoder functions
*
@verbatim
==============================================================================
##### TIM Encoder functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Initialize and configure the TIM Encoder.
(+) De-initialize the TIM Encoder.
(+) Start the TIM Encoder.
(+) Stop the TIM Encoder.
(+) Start the TIM Encoder and enable interrupt.
(+) Stop the TIM Encoder and disable interrupt.
(+) Start the TIM Encoder and enable DMA transfer.
(+) Stop the TIM Encoder and disable DMA transfer.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM Encoder Interface and initialize the associated handle.
* @note Switching from Center Aligned counter mode to Edge counter mode (or reverse)
* requires a timer reset to avoid unexpected direction
* due to DIR bit readonly in center aligned mode.
* Ex: call @ref HAL_TIM_Encoder_DeInit() before HAL_TIM_Encoder_Init()
* @note Encoder mode and External clock mode 2 are not compatible and must not be selected together
* Ex: A call for @ref HAL_TIM_Encoder_Init will erase the settings of @ref HAL_TIM_ConfigClockSource
* using TIM_CLOCKSOURCE_ETRMODE2 and vice versa
* @param htim TIM Encoder Interface handle
* @param sConfig TIM Encoder Interface configuration structure
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_Init(TIM_HandleTypeDef *htim, TIM_Encoder_InitTypeDef *sConfig)
{
uint32_t tmpsmcr;
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Check the TIM handle allocation */
if (htim == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
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_CC2_INSTANCE(htim->Instance));
assert_param(IS_TIM_ENCODER_MODE(sConfig->EncoderMode));
assert_param(IS_TIM_IC_SELECTION(sConfig->IC1Selection));
assert_param(IS_TIM_IC_SELECTION(sConfig->IC2Selection));
assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC1Polarity));
assert_param(IS_TIM_ENCODERINPUT_POLARITY(sConfig->IC2Polarity));
assert_param(IS_TIM_IC_PRESCALER(sConfig->IC1Prescaler));
assert_param(IS_TIM_IC_PRESCALER(sConfig->IC2Prescaler));
assert_param(IS_TIM_IC_FILTER(sConfig->IC1Filter));
assert_param(IS_TIM_IC_FILTER(sConfig->IC2Filter));
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 weak callbacks */
TIM_ResetCallback(htim);
if (htim->Encoder_MspInitCallback == NULL)
{
htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit;
}
/* Init the low level hardware : GPIO, CLOCK, NVIC */
htim->Encoder_MspInitCallback(htim);
#else
/* Init the low level hardware : GPIO, CLOCK, NVIC and DMA */
HAL_TIM_Encoder_MspInit(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Set the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Reset the SMS and ECE bits */
htim->Instance->SMCR &= ~(TIM_SMCR_SMS | TIM_SMCR_ECE);
/* Configure the Time base in the Encoder Mode */
TIM_Base_SetConfig(htim->Instance, &htim->Init);
/* Get the TIMx SMCR register value */
tmpsmcr = htim->Instance->SMCR;
/* Get the TIMx CCMR1 register value */
tmpccmr1 = htim->Instance->CCMR1;
/* Get the TIMx CCER register value */
tmpccer = htim->Instance->CCER;
/* Set the encoder Mode */
tmpsmcr |= sConfig->EncoderMode;
/* Select the Capture Compare 1 and the Capture Compare 2 as input */
tmpccmr1 &= ~(TIM_CCMR1_CC1S | TIM_CCMR1_CC2S);
tmpccmr1 |= (sConfig->IC1Selection | (sConfig->IC2Selection << 8U));
/* Set the Capture Compare 1 and the Capture Compare 2 prescalers and filters */
tmpccmr1 &= ~(TIM_CCMR1_IC1PSC | TIM_CCMR1_IC2PSC);
tmpccmr1 &= ~(TIM_CCMR1_IC1F | TIM_CCMR1_IC2F);
tmpccmr1 |= sConfig->IC1Prescaler | (sConfig->IC2Prescaler << 8U);
tmpccmr1 |= (sConfig->IC1Filter << 4U) | (sConfig->IC2Filter << 12U);
/* Set the TI1 and the TI2 Polarities */
tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC2P);
tmpccer &= ~(TIM_CCER_CC1NP | TIM_CCER_CC2NP);
tmpccer |= sConfig->IC1Polarity | (sConfig->IC2Polarity << 4U);
/* Write to TIMx SMCR */
htim->Instance->SMCR = tmpsmcr;
/* Write to TIMx CCMR1 */
htim->Instance->CCMR1 = tmpccmr1;
/* Write to TIMx CCER */
htim->Instance->CCER = tmpccer;
/* Initialize the TIM state*/
htim->State = HAL_TIM_STATE_READY;
return HAL_OK;
}
/**
* @brief DeInitializes the TIM Encoder interface
* @param htim TIM Encoder Interface handle
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_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->Encoder_MspDeInitCallback == NULL)
{
htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit;
}
/* DeInit the low level hardware */
htim->Encoder_MspDeInitCallback(htim);
#else
/* DeInit the low level hardware: GPIO, CLOCK, NVIC */
HAL_TIM_Encoder_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 Encoder Interface MSP.
* @param htim TIM Encoder Interface handle
* @retval None
*/
__weak void HAL_TIM_Encoder_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_TIM_Encoder_MspInit could be implemented in the user file
*/
}
/**
* @brief DeInitializes TIM Encoder Interface MSP.
* @param htim TIM Encoder Interface handle
* @retval None
*/
__weak void HAL_TIM_Encoder_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_TIM_Encoder_MspDeInit could be implemented in the user file
*/
}
/**
* @brief Starts the TIM Encoder Interface.
* @param htim TIM Encoder Interface handle
* @param Channel TIM Channels 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_ALL: TIM Channel 1 and TIM Channel 2 are selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Enable the encoder interface channels */
switch (Channel)
{
case TIM_CHANNEL_1:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
break;
}
case TIM_CHANNEL_2:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
break;
}
default :
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
break;
}
}
/* Enable the Peripheral */
__HAL_TIM_ENABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @brief Stops the TIM Encoder Interface.
* @param htim TIM Encoder Interface handle
* @param Channel TIM Channels 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_ALL: TIM Channel 1 and TIM Channel 2 are selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_Stop(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Disable the Input Capture channels 1 and 2
(in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
switch (Channel)
{
case TIM_CHANNEL_1:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
break;
}
case TIM_CHANNEL_2:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
break;
}
default :
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
break;
}
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @brief Starts the TIM Encoder Interface in interrupt mode.
* @param htim TIM Encoder Interface handle
* @param Channel TIM Channels 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_ALL: TIM Channel 1 and TIM Channel 2 are selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_Start_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Enable the encoder interface channels */
/* Enable the capture compare Interrupts 1 and/or 2 */
switch (Channel)
{
case TIM_CHANNEL_1:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
break;
}
case TIM_CHANNEL_2:
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
break;
}
default :
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_ENABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_ENABLE);
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC1);
__HAL_TIM_ENABLE_IT(htim, TIM_IT_CC2);
break;
}
}
/* Enable the Peripheral */
__HAL_TIM_ENABLE(htim);
/* Return function status */
return HAL_OK;
}
/**
* @brief Stops the TIM Encoder Interface in interrupt mode.
* @param htim TIM Encoder Interface handle
* @param Channel TIM Channels 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_ALL: TIM Channel 1 and TIM Channel 2 are selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_Encoder_Stop_IT(TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Disable the Input Capture channels 1 and 2
(in the EncoderInterface the two possible channels that can be used are TIM_CHANNEL_1 and TIM_CHANNEL_2) */
if (Channel == TIM_CHANNEL_1)
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
/* Disable the capture compare Interrupts 1 */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
}
else if (Channel == TIM_CHANNEL_2)
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
/* Disable the capture compare Interrupts 2 */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
}
else
{
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_1, TIM_CCx_DISABLE);
TIM_CCxChannelCmd(htim->Instance, TIM_CHANNEL_2, TIM_CCx_DISABLE);
/* Disable the capture compare Interrupts 1 and 2 */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Change the htim state */
htim->State = HAL_TIM_STATE_READY;
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group7 TIM IRQ handler management
* @brief TIM IRQ handler management
*
@verbatim
==============================================================================
##### IRQ handler management #####
==============================================================================
[..]
This section provides Timer IRQ handler function.
@endverbatim
* @{
*/
/**
* @brief This function handles TIM interrupts requests.
* @param htim TIM handle
* @retval None
*/
void HAL_TIM_IRQHandler(TIM_HandleTypeDef *htim)
{
/* Capture compare 1 event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC1) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC1) != RESET)
{
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC1);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_1;
/* Input capture event */
if ((htim->Instance->CCMR1 & TIM_CCMR1_CC1S) != 0x00U)
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->IC_CaptureCallback(htim);
#else
HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Output compare event */
else
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->OC_DelayElapsedCallback(htim);
htim->PWM_PulseFinishedCallback(htim);
#else
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
}
/* Capture compare 2 event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC2) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC2) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC2);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_2;
/* Input capture event */
if ((htim->Instance->CCMR1 & TIM_CCMR1_CC2S) != 0x00U)
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->IC_CaptureCallback(htim);
#else
HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Output compare event */
else
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->OC_DelayElapsedCallback(htim);
htim->PWM_PulseFinishedCallback(htim);
#else
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 3 event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC3) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC3) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC3);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_3;
/* Input capture event */
if ((htim->Instance->CCMR2 & TIM_CCMR2_CC3S) != 0x00U)
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->IC_CaptureCallback(htim);
#else
HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Output compare event */
else
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->OC_DelayElapsedCallback(htim);
htim->PWM_PulseFinishedCallback(htim);
#else
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* Capture compare 4 event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_CC4) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_CC4) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_CC4);
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_4;
/* Input capture event */
if ((htim->Instance->CCMR2 & TIM_CCMR2_CC4S) != 0x00U)
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->IC_CaptureCallback(htim);
#else
HAL_TIM_IC_CaptureCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
/* Output compare event */
else
{
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->OC_DelayElapsedCallback(htim);
htim->PWM_PulseFinishedCallback(htim);
#else
HAL_TIM_OC_DelayElapsedCallback(htim);
HAL_TIM_PWM_PulseFinishedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
htim->Channel = HAL_TIM_ACTIVE_CHANNEL_CLEARED;
}
}
/* TIM Update event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_UPDATE) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_UPDATE) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_UPDATE);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->PeriodElapsedCallback(htim);
#else
HAL_TIM_PeriodElapsedCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
/* TIM Break input event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_BREAK) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_BREAK) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_BREAK);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->BreakCallback(htim);
#else
HAL_TIMEx_BreakCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
/* TIM Trigger detection event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_TRIGGER) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_TRIGGER) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_IT_TRIGGER);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->TriggerCallback(htim);
#else
HAL_TIM_TriggerCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
/* TIM commutation event */
if (__HAL_TIM_GET_FLAG(htim, TIM_FLAG_COM) != RESET)
{
if (__HAL_TIM_GET_IT_SOURCE(htim, TIM_IT_COM) != RESET)
{
__HAL_TIM_CLEAR_IT(htim, TIM_FLAG_COM);
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
htim->CommutationCallback(htim);
#else
HAL_TIMEx_CommutCallback(htim);
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
}
}
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group8 TIM Peripheral Control functions
* @brief TIM Peripheral Control functions
*
@verbatim
==============================================================================
##### Peripheral Control functions #####
==============================================================================
[..]
This section provides functions allowing to:
(+) Configure The Input Output channels for OC, PWM, IC or One Pulse mode.
(+) Configure External Clock source.
(+) Configure Complementary channels, break features and dead time.
(+) Configure Master and the Slave synchronization.
(+) Configure the DMA Burst Mode.
@endverbatim
* @{
*/
/**
* @brief Initializes the TIM Output Compare Channels according to the specified
* parameters in the TIM_OC_InitTypeDef.
* @param htim TIM Output Compare handle
* @param sConfig TIM Output Compare configuration structure
* @param Channel TIM Channels to configure
* 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OC_ConfigChannel(TIM_HandleTypeDef *htim,
TIM_OC_InitTypeDef *sConfig,
uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CHANNELS(Channel));
assert_param(IS_TIM_OC_MODE(sConfig->OCMode));
assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
switch (Channel)
{
case TIM_CHANNEL_1:
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
/* Configure the TIM Channel 1 in Output Compare */
TIM_OC1_SetConfig(htim->Instance, sConfig);
break;
}
case TIM_CHANNEL_2:
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Configure the TIM Channel 2 in Output Compare */
TIM_OC2_SetConfig(htim->Instance, sConfig);
break;
}
case TIM_CHANNEL_3:
{
/* Check the parameters */
assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
/* Configure the TIM Channel 3 in Output Compare */
TIM_OC3_SetConfig(htim->Instance, sConfig);
break;
}
case TIM_CHANNEL_4:
{
/* Check the parameters */
assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
/* Configure the TIM Channel 4 in Output Compare */
TIM_OC4_SetConfig(htim->Instance, sConfig);
break;
}
default:
break;
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Initializes the TIM Input Capture Channels according to the specified
* parameters in the TIM_IC_InitTypeDef.
* @param htim TIM IC handle
* @param sConfig TIM Input Capture configuration structure
* @param Channel TIM Channel to configure
* 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_IC_ConfigChannel(TIM_HandleTypeDef *htim, TIM_IC_InitTypeDef *sConfig, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
assert_param(IS_TIM_IC_POLARITY(sConfig->ICPolarity));
assert_param(IS_TIM_IC_SELECTION(sConfig->ICSelection));
assert_param(IS_TIM_IC_PRESCALER(sConfig->ICPrescaler));
assert_param(IS_TIM_IC_FILTER(sConfig->ICFilter));
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
if (Channel == TIM_CHANNEL_1)
{
/* TI1 Configuration */
TIM_TI1_SetConfig(htim->Instance,
sConfig->ICPolarity,
sConfig->ICSelection,
sConfig->ICFilter);
/* Reset the IC1PSC Bits */
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
/* Set the IC1PSC value */
htim->Instance->CCMR1 |= sConfig->ICPrescaler;
}
else if (Channel == TIM_CHANNEL_2)
{
/* TI2 Configuration */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
TIM_TI2_SetConfig(htim->Instance,
sConfig->ICPolarity,
sConfig->ICSelection,
sConfig->ICFilter);
/* Reset the IC2PSC Bits */
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
/* Set the IC2PSC value */
htim->Instance->CCMR1 |= (sConfig->ICPrescaler << 8U);
}
else if (Channel == TIM_CHANNEL_3)
{
/* TI3 Configuration */
assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
TIM_TI3_SetConfig(htim->Instance,
sConfig->ICPolarity,
sConfig->ICSelection,
sConfig->ICFilter);
/* Reset the IC3PSC Bits */
htim->Instance->CCMR2 &= ~TIM_CCMR2_IC3PSC;
/* Set the IC3PSC value */
htim->Instance->CCMR2 |= sConfig->ICPrescaler;
}
else
{
/* TI4 Configuration */
assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
TIM_TI4_SetConfig(htim->Instance,
sConfig->ICPolarity,
sConfig->ICSelection,
sConfig->ICFilter);
/* Reset the IC4PSC Bits */
htim->Instance->CCMR2 &= ~TIM_CCMR2_IC4PSC;
/* Set the IC4PSC value */
htim->Instance->CCMR2 |= (sConfig->ICPrescaler << 8U);
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Initializes the TIM PWM channels according to the specified
* parameters in the TIM_OC_InitTypeDef.
* @param htim TIM PWM handle
* @param sConfig TIM PWM configuration structure
* @param Channel TIM Channels to be configured
* 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_ConfigChannel(TIM_HandleTypeDef *htim,
TIM_OC_InitTypeDef *sConfig,
uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CHANNELS(Channel));
assert_param(IS_TIM_PWM_MODE(sConfig->OCMode));
assert_param(IS_TIM_OC_POLARITY(sConfig->OCPolarity));
assert_param(IS_TIM_FAST_STATE(sConfig->OCFastMode));
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
switch (Channel)
{
case TIM_CHANNEL_1:
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
/* Configure the Channel 1 in PWM mode */
TIM_OC1_SetConfig(htim->Instance, sConfig);
/* Set the Preload enable bit for channel1 */
htim->Instance->CCMR1 |= TIM_CCMR1_OC1PE;
/* Configure the Output Fast mode */
htim->Instance->CCMR1 &= ~TIM_CCMR1_OC1FE;
htim->Instance->CCMR1 |= sConfig->OCFastMode;
break;
}
case TIM_CHANNEL_2:
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Configure the Channel 2 in PWM mode */
TIM_OC2_SetConfig(htim->Instance, sConfig);
/* Set the Preload enable bit for channel2 */
htim->Instance->CCMR1 |= TIM_CCMR1_OC2PE;
/* Configure the Output Fast mode */
htim->Instance->CCMR1 &= ~TIM_CCMR1_OC2FE;
htim->Instance->CCMR1 |= sConfig->OCFastMode << 8U;
break;
}
case TIM_CHANNEL_3:
{
/* Check the parameters */
assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
/* Configure the Channel 3 in PWM mode */
TIM_OC3_SetConfig(htim->Instance, sConfig);
/* Set the Preload enable bit for channel3 */
htim->Instance->CCMR2 |= TIM_CCMR2_OC3PE;
/* Configure the Output Fast mode */
htim->Instance->CCMR2 &= ~TIM_CCMR2_OC3FE;
htim->Instance->CCMR2 |= sConfig->OCFastMode;
break;
}
case TIM_CHANNEL_4:
{
/* Check the parameters */
assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
/* Configure the Channel 4 in PWM mode */
TIM_OC4_SetConfig(htim->Instance, sConfig);
/* Set the Preload enable bit for channel4 */
htim->Instance->CCMR2 |= TIM_CCMR2_OC4PE;
/* Configure the Output Fast mode */
htim->Instance->CCMR2 &= ~TIM_CCMR2_OC4FE;
htim->Instance->CCMR2 |= sConfig->OCFastMode << 8U;
break;
}
default:
break;
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Initializes the TIM One Pulse Channels according to the specified
* parameters in the TIM_OnePulse_InitTypeDef.
* @param htim TIM One Pulse handle
* @param sConfig TIM One Pulse configuration structure
* @param OutputChannel TIM output channel to configure
* 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
* @param InputChannel TIM input Channel to configure
* 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
* @note To output a waveform with a minimum delay user can enable the fast
* mode by calling the @ref __HAL_TIM_ENABLE_OCxFAST macro. Then CCx
* output is forced in response to the edge detection on TIx input,
* without taking in account the comparison.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_OnePulse_ConfigChannel(TIM_HandleTypeDef *htim, TIM_OnePulse_InitTypeDef *sConfig,
uint32_t OutputChannel, uint32_t InputChannel)
{
TIM_OC_InitTypeDef temp1;
/* Check the parameters */
assert_param(IS_TIM_OPM_CHANNELS(OutputChannel));
assert_param(IS_TIM_OPM_CHANNELS(InputChannel));
if (OutputChannel != InputChannel)
{
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
/* Extract the Output compare configuration from sConfig structure */
temp1.OCMode = sConfig->OCMode;
temp1.Pulse = sConfig->Pulse;
temp1.OCPolarity = sConfig->OCPolarity;
temp1.OCNPolarity = sConfig->OCNPolarity;
temp1.OCIdleState = sConfig->OCIdleState;
temp1.OCNIdleState = sConfig->OCNIdleState;
switch (OutputChannel)
{
case TIM_CHANNEL_1:
{
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
TIM_OC1_SetConfig(htim->Instance, &temp1);
break;
}
case TIM_CHANNEL_2:
{
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
TIM_OC2_SetConfig(htim->Instance, &temp1);
break;
}
default:
break;
}
switch (InputChannel)
{
case TIM_CHANNEL_1:
{
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
TIM_TI1_SetConfig(htim->Instance, sConfig->ICPolarity,
sConfig->ICSelection, sConfig->ICFilter);
/* Reset the IC1PSC Bits */
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC1PSC;
/* Select the Trigger source */
htim->Instance->SMCR &= ~TIM_SMCR_TS;
htim->Instance->SMCR |= TIM_TS_TI1FP1;
/* Select the Slave Mode */
htim->Instance->SMCR &= ~TIM_SMCR_SMS;
htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
break;
}
case TIM_CHANNEL_2:
{
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
TIM_TI2_SetConfig(htim->Instance, sConfig->ICPolarity,
sConfig->ICSelection, sConfig->ICFilter);
/* Reset the IC2PSC Bits */
htim->Instance->CCMR1 &= ~TIM_CCMR1_IC2PSC;
/* Select the Trigger source */
htim->Instance->SMCR &= ~TIM_SMCR_TS;
htim->Instance->SMCR |= TIM_TS_TI2FP2;
/* Select the Slave Mode */
htim->Instance->SMCR &= ~TIM_SMCR_SMS;
htim->Instance->SMCR |= TIM_SLAVEMODE_TRIGGER;
break;
}
default:
break;
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
else
{
return HAL_ERROR;
}
}
/**
* @brief Generate a software event
* @param htim TIM handle
* @param EventSource specifies the event source.
* This parameter can be one of the following values:
* @arg TIM_EVENTSOURCE_UPDATE: Timer update Event source
* @arg TIM_EVENTSOURCE_CC1: Timer Capture Compare 1 Event source
* @arg TIM_EVENTSOURCE_CC2: Timer Capture Compare 2 Event source
* @arg TIM_EVENTSOURCE_CC3: Timer Capture Compare 3 Event source
* @arg TIM_EVENTSOURCE_CC4: Timer Capture Compare 4 Event source
* @arg TIM_EVENTSOURCE_COM: Timer COM event source
* @arg TIM_EVENTSOURCE_TRIGGER: Timer Trigger Event source
* @arg TIM_EVENTSOURCE_BREAK: Timer Break event source
* @note Basic timers can only generate an update event.
* @note TIM_EVENTSOURCE_COM is relevant only with advanced timer instances.
* @note TIM_EVENTSOURCE_BREAK are relevant only for timer instances
* supporting a break input.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_GenerateEvent(TIM_HandleTypeDef *htim, uint32_t EventSource)
{
/* Check the parameters */
assert_param(IS_TIM_INSTANCE(htim->Instance));
assert_param(IS_TIM_EVENT_SOURCE(EventSource));
/* Process Locked */
__HAL_LOCK(htim);
/* Change the TIM state */
htim->State = HAL_TIM_STATE_BUSY;
/* Set the event sources */
htim->Instance->EGR = EventSource;
/* Change the TIM state */
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
/* Return function status */
return HAL_OK;
}
/**
* @brief Configures the OCRef clear feature
* @param htim TIM handle
* @param sClearInputConfig pointer to a TIM_ClearInputConfigTypeDef structure that
* contains the OCREF clear feature and parameters for 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
* @arg TIM_CHANNEL_4: TIM Channel 4
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_ConfigOCrefClear(TIM_HandleTypeDef *htim,
TIM_ClearInputConfigTypeDef *sClearInputConfig,
uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_OCXREF_CLEAR_INSTANCE(htim->Instance));
assert_param(IS_TIM_CLEARINPUT_SOURCE(sClearInputConfig->ClearInputSource));
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
switch (sClearInputConfig->ClearInputSource)
{
case TIM_CLEARINPUTSOURCE_NONE:
{
/* Clear the OCREF clear selection bit and the the ETR Bits */
CLEAR_BIT(htim->Instance->SMCR, (TIM_SMCR_OCCS | TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP));
break;
}
case TIM_CLEARINPUTSOURCE_OCREFCLR:
{
/* Clear the OCREF clear selection bit */
CLEAR_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS);
}
break;
case TIM_CLEARINPUTSOURCE_ETR:
{
/* Check the parameters */
assert_param(IS_TIM_CLEARINPUT_POLARITY(sClearInputConfig->ClearInputPolarity));
assert_param(IS_TIM_CLEARINPUT_PRESCALER(sClearInputConfig->ClearInputPrescaler));
assert_param(IS_TIM_CLEARINPUT_FILTER(sClearInputConfig->ClearInputFilter));
/* When OCRef clear feature is used with ETR source, ETR prescaler must be off */
if (sClearInputConfig->ClearInputPrescaler != TIM_CLEARINPUTPRESCALER_DIV1)
{
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_ERROR;
}
TIM_ETR_SetConfig(htim->Instance,
sClearInputConfig->ClearInputPrescaler,
sClearInputConfig->ClearInputPolarity,
sClearInputConfig->ClearInputFilter);
/* Set the OCREF clear selection bit */
SET_BIT(htim->Instance->SMCR, TIM_SMCR_OCCS);
break;
}
default:
break;
}
switch (Channel)
{
case TIM_CHANNEL_1:
{
if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
{
/* Enable the OCREF clear feature for Channel 1 */
SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE);
}
else
{
/* Disable the OCREF clear feature for Channel 1 */
CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC1CE);
}
break;
}
case TIM_CHANNEL_2:
{
if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
{
/* Enable the OCREF clear feature for Channel 2 */
SET_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE);
}
else
{
/* Disable the OCREF clear feature for Channel 2 */
CLEAR_BIT(htim->Instance->CCMR1, TIM_CCMR1_OC2CE);
}
break;
}
case TIM_CHANNEL_3:
{
if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
{
/* Enable the OCREF clear feature for Channel 3 */
SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE);
}
else
{
/* Disable the OCREF clear feature for Channel 3 */
CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC3CE);
}
break;
}
case TIM_CHANNEL_4:
{
if (sClearInputConfig->ClearInputState != (uint32_t)DISABLE)
{
/* Enable the OCREF clear feature for Channel 4 */
SET_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE);
}
else
{
/* Disable the OCREF clear feature for Channel 4 */
CLEAR_BIT(htim->Instance->CCMR2, TIM_CCMR2_OC4CE);
}
break;
}
default:
break;
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Configures the clock source to be used
* @param htim TIM handle
* @param sClockSourceConfig pointer to a TIM_ClockConfigTypeDef structure that
* contains the clock source information for the TIM peripheral.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_ConfigClockSource(TIM_HandleTypeDef *htim, TIM_ClockConfigTypeDef *sClockSourceConfig)
{
uint32_t tmpsmcr;
/* Process Locked */
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
/* Check the parameters */
assert_param(IS_TIM_CLOCKSOURCE(sClockSourceConfig->ClockSource));
/* Reset the SMS, TS, ECE, ETPS and ETRF bits */
tmpsmcr = htim->Instance->SMCR;
tmpsmcr &= ~(TIM_SMCR_SMS | TIM_SMCR_TS);
tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
htim->Instance->SMCR = tmpsmcr;
switch (sClockSourceConfig->ClockSource)
{
case TIM_CLOCKSOURCE_INTERNAL:
{
assert_param(IS_TIM_INSTANCE(htim->Instance));
break;
}
case TIM_CLOCKSOURCE_ETRMODE1:
{
/* Check whether or not the timer instance supports external trigger input mode 1 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
/* Check ETR input conditioning related parameters */
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
/* Configure the ETR Clock source */
TIM_ETR_SetConfig(htim->Instance,
sClockSourceConfig->ClockPrescaler,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
/* Select the External clock mode1 and the ETRF trigger */
tmpsmcr = htim->Instance->SMCR;
tmpsmcr |= (TIM_SLAVEMODE_EXTERNAL1 | TIM_CLOCKSOURCE_ETRMODE1);
/* Write to TIMx SMCR */
htim->Instance->SMCR = tmpsmcr;
break;
}
case TIM_CLOCKSOURCE_ETRMODE2:
{
/* Check whether or not the timer instance supports external trigger input mode 2 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE2_INSTANCE(htim->Instance));
/* Check ETR input conditioning related parameters */
assert_param(IS_TIM_CLOCKPRESCALER(sClockSourceConfig->ClockPrescaler));
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
/* Configure the ETR Clock source */
TIM_ETR_SetConfig(htim->Instance,
sClockSourceConfig->ClockPrescaler,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
/* Enable the External clock mode2 */
htim->Instance->SMCR |= TIM_SMCR_ECE;
break;
}
case TIM_CLOCKSOURCE_TI1:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI1 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI1_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1);
break;
}
case TIM_CLOCKSOURCE_TI2:
{
/* Check whether or not the timer instance supports external clock mode 1 (ETRF)*/
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI2 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI2_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI2);
break;
}
case TIM_CLOCKSOURCE_TI1ED:
{
/* Check whether or not the timer instance supports external clock mode 1 */
assert_param(IS_TIM_CLOCKSOURCE_TIX_INSTANCE(htim->Instance));
/* Check TI1 input conditioning related parameters */
assert_param(IS_TIM_CLOCKPOLARITY(sClockSourceConfig->ClockPolarity));
assert_param(IS_TIM_CLOCKFILTER(sClockSourceConfig->ClockFilter));
TIM_TI1_ConfigInputStage(htim->Instance,
sClockSourceConfig->ClockPolarity,
sClockSourceConfig->ClockFilter);
TIM_ITRx_SetConfig(htim->Instance, TIM_CLOCKSOURCE_TI1ED);
break;
}
case TIM_CLOCKSOURCE_ITR0:
case TIM_CLOCKSOURCE_ITR1:
case TIM_CLOCKSOURCE_ITR2:
case TIM_CLOCKSOURCE_ITR3:
{
/* Check whether or not the timer instance supports internal trigger input */
assert_param(IS_TIM_CLOCKSOURCE_ITRX_INSTANCE(htim->Instance));
TIM_ITRx_SetConfig(htim->Instance, sClockSourceConfig->ClockSource);
break;
}
default:
break;
}
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Selects the signal connected to the TI1 input: direct from CH1_input
* or a XOR combination between CH1_input, CH2_input & CH3_input
* @param htim TIM handle.
* @param TI1_Selection Indicate whether or not channel 1 is connected to the
* output of a XOR gate.
* This parameter can be one of the following values:
* @arg TIM_TI1SELECTION_CH1: The TIMx_CH1 pin is connected to TI1 input
* @arg TIM_TI1SELECTION_XORCOMBINATION: The TIMx_CH1, CH2 and CH3
* pins are connected to the TI1 input (XOR combination)
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_ConfigTI1Input(TIM_HandleTypeDef *htim, uint32_t TI1_Selection)
{
uint32_t tmpcr2;
/* Check the parameters */
assert_param(IS_TIM_XOR_INSTANCE(htim->Instance));
assert_param(IS_TIM_TI1SELECTION(TI1_Selection));
/* Get the TIMx CR2 register value */
tmpcr2 = htim->Instance->CR2;
/* Reset the TI1 selection */
tmpcr2 &= ~TIM_CR2_TI1S;
/* Set the TI1 selection */
tmpcr2 |= TI1_Selection;
/* Write to TIMxCR2 */
htim->Instance->CR2 = tmpcr2;
return HAL_OK;
}
/**
* @brief Configures the TIM in Slave mode
* @param htim TIM handle.
* @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that
* contains the selected trigger (internal trigger input, filtered
* timer input or external trigger input) and the Slave mode
* (Disable, Reset, Gated, Trigger, External clock mode 1).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro(TIM_HandleTypeDef *htim, TIM_SlaveConfigTypeDef *sSlaveConfig)
{
/* Check the parameters */
assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK)
{
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_ERROR;
}
/* Disable Trigger Interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_TRIGGER);
#if (defined(DMA) || defined(DMA1))
/* Disable Trigger DMA request */
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
#endif
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Configures the TIM in Slave mode in interrupt mode
* @param htim TIM handle.
* @param sSlaveConfig pointer to a TIM_SlaveConfigTypeDef structure that
* contains the selected trigger (internal trigger input, filtered
* timer input or external trigger input) and the Slave mode
* (Disable, Reset, Gated, Trigger, External clock mode 1).
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_SlaveConfigSynchro_IT(TIM_HandleTypeDef *htim,
TIM_SlaveConfigTypeDef *sSlaveConfig)
{
/* Check the parameters */
assert_param(IS_TIM_SLAVE_INSTANCE(htim->Instance));
assert_param(IS_TIM_SLAVE_MODE(sSlaveConfig->SlaveMode));
assert_param(IS_TIM_TRIGGER_SELECTION(sSlaveConfig->InputTrigger));
__HAL_LOCK(htim);
htim->State = HAL_TIM_STATE_BUSY;
if (TIM_SlaveTimer_SetConfig(htim, sSlaveConfig) != HAL_OK)
{
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_ERROR;
}
/* Enable Trigger Interrupt */
__HAL_TIM_ENABLE_IT(htim, TIM_IT_TRIGGER);
#if (defined(DMA) || defined(DMA1))
/* Disable Trigger DMA request */
__HAL_TIM_DISABLE_DMA(htim, TIM_DMA_TRIGGER);
#endif
htim->State = HAL_TIM_STATE_READY;
__HAL_UNLOCK(htim);
return HAL_OK;
}
/**
* @brief Read the captured value from Capture Compare unit
* @param htim TIM handle.
* @param Channel TIM Channels 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
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval Captured value
*/
uint32_t HAL_TIM_ReadCapturedValue(TIM_HandleTypeDef *htim, uint32_t Channel)
{
uint32_t tmpreg = 0U;
switch (Channel)
{
case TIM_CHANNEL_1:
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
/* Return the capture 1 value */
tmpreg = htim->Instance->CCR1;
break;
}
case TIM_CHANNEL_2:
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
/* Return the capture 2 value */
tmpreg = htim->Instance->CCR2;
break;
}
case TIM_CHANNEL_3:
{
/* Check the parameters */
assert_param(IS_TIM_CC3_INSTANCE(htim->Instance));
/* Return the capture 3 value */
tmpreg = htim->Instance->CCR3;
break;
}
case TIM_CHANNEL_4:
{
/* Check the parameters */
assert_param(IS_TIM_CC4_INSTANCE(htim->Instance));
/* Return the capture 4 value */
tmpreg = htim->Instance->CCR4;
break;
}
default:
break;
}
return tmpreg;
}
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group9 TIM Callbacks functions
* @brief TIM Callbacks functions
*
@verbatim
==============================================================================
##### TIM Callbacks functions #####
==============================================================================
[..]
This section provides TIM callback functions:
(+) TIM Period elapsed callback
(+) TIM Output Compare callback
(+) TIM Input capture callback
(+) TIM Trigger callback
(+) TIM Error callback
@endverbatim
* @{
*/
/**
* @brief Period elapsed callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_PeriodElapsedCallback(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_TIM_PeriodElapsedCallback could be implemented in the user file
*/
}
/**
* @brief Period elapsed half complete callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_PeriodElapsedHalfCpltCallback(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_TIM_PeriodElapsedHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief Output Compare callback in non-blocking mode
* @param htim TIM OC handle
* @retval None
*/
__weak void HAL_TIM_OC_DelayElapsedCallback(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_TIM_OC_DelayElapsedCallback could be implemented in the user file
*/
}
/**
* @brief Input Capture callback in non-blocking mode
* @param htim TIM IC handle
* @retval None
*/
__weak void HAL_TIM_IC_CaptureCallback(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_TIM_IC_CaptureCallback could be implemented in the user file
*/
}
/**
* @brief Input Capture half complete callback in non-blocking mode
* @param htim TIM IC handle
* @retval None
*/
__weak void HAL_TIM_IC_CaptureHalfCpltCallback(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_TIM_IC_CaptureHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief PWM Pulse finished callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_PWM_PulseFinishedCallback(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_TIM_PWM_PulseFinishedCallback could be implemented in the user file
*/
}
/**
* @brief PWM Pulse finished half complete callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_PWM_PulseFinishedHalfCpltCallback(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_TIM_PWM_PulseFinishedHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief Hall Trigger detection callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_TriggerCallback(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_TIM_TriggerCallback could be implemented in the user file
*/
}
/**
* @brief Hall Trigger detection half complete callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_TriggerHalfCpltCallback(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_TIM_TriggerHalfCpltCallback could be implemented in the user file
*/
}
/**
* @brief Timer error callback in non-blocking mode
* @param htim TIM handle
* @retval None
*/
__weak void HAL_TIM_ErrorCallback(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_TIM_ErrorCallback could be implemented in the user file
*/
}
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
/**
* @brief Register a User TIM callback to be used instead of the weak predefined callback
* @param htim tim handle
* @param CallbackID ID of the callback to be registered
* This parameter can be one of the following values:
* @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID
* @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID
* @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID
* @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID
* @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID
* @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID
* @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID
* @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID
* @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID
* @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID
* @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID
* @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID
* @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID
* @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID
* @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID
* @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID
* @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID
* @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID
* @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID
* @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID
* @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID
* @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID
* @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID
* @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID
* @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID
* @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID
* @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID
* @param pCallback pointer to the callback function
* @retval status
*/
HAL_StatusTypeDef HAL_TIM_RegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID,
pTIM_CallbackTypeDef pCallback)
{
HAL_StatusTypeDef status = HAL_OK;
if (pCallback == NULL)
{
return HAL_ERROR;
}
/* Process locked */
__HAL_LOCK(htim);
if (htim->State == HAL_TIM_STATE_READY)
{
switch (CallbackID)
{
case HAL_TIM_BASE_MSPINIT_CB_ID :
htim->Base_MspInitCallback = pCallback;
break;
case HAL_TIM_BASE_MSPDEINIT_CB_ID :
htim->Base_MspDeInitCallback = pCallback;
break;
case HAL_TIM_IC_MSPINIT_CB_ID :
htim->IC_MspInitCallback = pCallback;
break;
case HAL_TIM_IC_MSPDEINIT_CB_ID :
htim->IC_MspDeInitCallback = pCallback;
break;
case HAL_TIM_OC_MSPINIT_CB_ID :
htim->OC_MspInitCallback = pCallback;
break;
case HAL_TIM_OC_MSPDEINIT_CB_ID :
htim->OC_MspDeInitCallback = pCallback;
break;
case HAL_TIM_PWM_MSPINIT_CB_ID :
htim->PWM_MspInitCallback = pCallback;
break;
case HAL_TIM_PWM_MSPDEINIT_CB_ID :
htim->PWM_MspDeInitCallback = pCallback;
break;
case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
htim->OnePulse_MspInitCallback = pCallback;
break;
case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
htim->OnePulse_MspDeInitCallback = pCallback;
break;
case HAL_TIM_ENCODER_MSPINIT_CB_ID :
htim->Encoder_MspInitCallback = pCallback;
break;
case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
htim->Encoder_MspDeInitCallback = pCallback;
break;
case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
htim->HallSensor_MspInitCallback = pCallback;
break;
case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
htim->HallSensor_MspDeInitCallback = pCallback;
break;
case HAL_TIM_PERIOD_ELAPSED_CB_ID :
htim->PeriodElapsedCallback = pCallback;
break;
case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID :
htim->PeriodElapsedHalfCpltCallback = pCallback;
break;
case HAL_TIM_TRIGGER_CB_ID :
htim->TriggerCallback = pCallback;
break;
case HAL_TIM_TRIGGER_HALF_CB_ID :
htim->TriggerHalfCpltCallback = pCallback;
break;
case HAL_TIM_IC_CAPTURE_CB_ID :
htim->IC_CaptureCallback = pCallback;
break;
case HAL_TIM_IC_CAPTURE_HALF_CB_ID :
htim->IC_CaptureHalfCpltCallback = pCallback;
break;
case HAL_TIM_OC_DELAY_ELAPSED_CB_ID :
htim->OC_DelayElapsedCallback = pCallback;
break;
case HAL_TIM_PWM_PULSE_FINISHED_CB_ID :
htim->PWM_PulseFinishedCallback = pCallback;
break;
case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID :
htim->PWM_PulseFinishedHalfCpltCallback = pCallback;
break;
case HAL_TIM_ERROR_CB_ID :
htim->ErrorCallback = pCallback;
break;
case HAL_TIM_COMMUTATION_CB_ID :
htim->CommutationCallback = pCallback;
break;
case HAL_TIM_COMMUTATION_HALF_CB_ID :
htim->CommutationHalfCpltCallback = pCallback;
break;
case HAL_TIM_BREAK_CB_ID :
htim->BreakCallback = pCallback;
break;
default :
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (htim->State == HAL_TIM_STATE_RESET)
{
switch (CallbackID)
{
case HAL_TIM_BASE_MSPINIT_CB_ID :
htim->Base_MspInitCallback = pCallback;
break;
case HAL_TIM_BASE_MSPDEINIT_CB_ID :
htim->Base_MspDeInitCallback = pCallback;
break;
case HAL_TIM_IC_MSPINIT_CB_ID :
htim->IC_MspInitCallback = pCallback;
break;
case HAL_TIM_IC_MSPDEINIT_CB_ID :
htim->IC_MspDeInitCallback = pCallback;
break;
case HAL_TIM_OC_MSPINIT_CB_ID :
htim->OC_MspInitCallback = pCallback;
break;
case HAL_TIM_OC_MSPDEINIT_CB_ID :
htim->OC_MspDeInitCallback = pCallback;
break;
case HAL_TIM_PWM_MSPINIT_CB_ID :
htim->PWM_MspInitCallback = pCallback;
break;
case HAL_TIM_PWM_MSPDEINIT_CB_ID :
htim->PWM_MspDeInitCallback = pCallback;
break;
case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
htim->OnePulse_MspInitCallback = pCallback;
break;
case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
htim->OnePulse_MspDeInitCallback = pCallback;
break;
case HAL_TIM_ENCODER_MSPINIT_CB_ID :
htim->Encoder_MspInitCallback = pCallback;
break;
case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
htim->Encoder_MspDeInitCallback = pCallback;
break;
case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
htim->HallSensor_MspInitCallback = pCallback;
break;
case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
htim->HallSensor_MspDeInitCallback = pCallback;
break;
default :
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Return error status */
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(htim);
return status;
}
/**
* @brief Unregister a TIM callback
* TIM callback is redirected to the weak predefined callback
* @param htim tim handle
* @param CallbackID ID of the callback to be unregistered
* This parameter can be one of the following values:
* @arg @ref HAL_TIM_BASE_MSPINIT_CB_ID Base MspInit Callback ID
* @arg @ref HAL_TIM_BASE_MSPDEINIT_CB_ID Base MspDeInit Callback ID
* @arg @ref HAL_TIM_IC_MSPINIT_CB_ID IC MspInit Callback ID
* @arg @ref HAL_TIM_IC_MSPDEINIT_CB_ID IC MspDeInit Callback ID
* @arg @ref HAL_TIM_OC_MSPINIT_CB_ID OC MspInit Callback ID
* @arg @ref HAL_TIM_OC_MSPDEINIT_CB_ID OC MspDeInit Callback ID
* @arg @ref HAL_TIM_PWM_MSPINIT_CB_ID PWM MspInit Callback ID
* @arg @ref HAL_TIM_PWM_MSPDEINIT_CB_ID PWM MspDeInit Callback ID
* @arg @ref HAL_TIM_ONE_PULSE_MSPINIT_CB_ID One Pulse MspInit Callback ID
* @arg @ref HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID One Pulse MspDeInit Callback ID
* @arg @ref HAL_TIM_ENCODER_MSPINIT_CB_ID Encoder MspInit Callback ID
* @arg @ref HAL_TIM_ENCODER_MSPDEINIT_CB_ID Encoder MspDeInit Callback ID
* @arg @ref HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID Hall Sensor MspInit Callback ID
* @arg @ref HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID Hall Sensor MspDeInit Callback ID
* @arg @ref HAL_TIM_PERIOD_ELAPSED_CB_ID Period Elapsed Callback ID
* @arg @ref HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID Period Elapsed half complete Callback ID
* @arg @ref HAL_TIM_TRIGGER_CB_ID Trigger Callback ID
* @arg @ref HAL_TIM_TRIGGER_HALF_CB_ID Trigger half complete Callback ID
* @arg @ref HAL_TIM_IC_CAPTURE_CB_ID Input Capture Callback ID
* @arg @ref HAL_TIM_IC_CAPTURE_HALF_CB_ID Input Capture half complete Callback ID
* @arg @ref HAL_TIM_OC_DELAY_ELAPSED_CB_ID Output Compare Delay Elapsed Callback ID
* @arg @ref HAL_TIM_PWM_PULSE_FINISHED_CB_ID PWM Pulse Finished Callback ID
* @arg @ref HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID PWM Pulse Finished half complete Callback ID
* @arg @ref HAL_TIM_ERROR_CB_ID Error Callback ID
* @arg @ref HAL_TIM_COMMUTATION_CB_ID Commutation Callback ID
* @arg @ref HAL_TIM_COMMUTATION_HALF_CB_ID Commutation half complete Callback ID
* @arg @ref HAL_TIM_BREAK_CB_ID Break Callback ID
* @retval status
*/
HAL_StatusTypeDef HAL_TIM_UnRegisterCallback(TIM_HandleTypeDef *htim, HAL_TIM_CallbackIDTypeDef CallbackID)
{
HAL_StatusTypeDef status = HAL_OK;
/* Process locked */
__HAL_LOCK(htim);
if (htim->State == HAL_TIM_STATE_READY)
{
switch (CallbackID)
{
case HAL_TIM_BASE_MSPINIT_CB_ID :
htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; /* Legacy weak Base MspInit Callback */
break;
case HAL_TIM_BASE_MSPDEINIT_CB_ID :
htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; /* Legacy weak Base Msp DeInit Callback */
break;
case HAL_TIM_IC_MSPINIT_CB_ID :
htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; /* Legacy weak IC Msp Init Callback */
break;
case HAL_TIM_IC_MSPDEINIT_CB_ID :
htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; /* Legacy weak IC Msp DeInit Callback */
break;
case HAL_TIM_OC_MSPINIT_CB_ID :
htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; /* Legacy weak OC Msp Init Callback */
break;
case HAL_TIM_OC_MSPDEINIT_CB_ID :
htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; /* Legacy weak OC Msp DeInit Callback */
break;
case HAL_TIM_PWM_MSPINIT_CB_ID :
htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; /* Legacy weak PWM Msp Init Callback */
break;
case HAL_TIM_PWM_MSPDEINIT_CB_ID :
htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; /* Legacy weak PWM Msp DeInit Callback */
break;
case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; /* Legacy weak One Pulse Msp Init Callback */
break;
case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; /* Legacy weak One Pulse Msp DeInit Callback */
break;
case HAL_TIM_ENCODER_MSPINIT_CB_ID :
htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; /* Legacy weak Encoder Msp Init Callback */
break;
case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; /* Legacy weak Encoder Msp DeInit Callback */
break;
case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; /* Legacy weak Hall Sensor Msp Init Callback */
break;
case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; /* Legacy weak Hall Sensor Msp DeInit Callback */
break;
case HAL_TIM_PERIOD_ELAPSED_CB_ID :
htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; /* Legacy weak Period Elapsed Callback */
break;
case HAL_TIM_PERIOD_ELAPSED_HALF_CB_ID :
htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; /* Legacy weak Period Elapsed half complete Callback */
break;
case HAL_TIM_TRIGGER_CB_ID :
htim->TriggerCallback = HAL_TIM_TriggerCallback; /* Legacy weak Trigger Callback */
break;
case HAL_TIM_TRIGGER_HALF_CB_ID :
htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; /* Legacy weak Trigger half complete Callback */
break;
case HAL_TIM_IC_CAPTURE_CB_ID :
htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; /* Legacy weak IC Capture Callback */
break;
case HAL_TIM_IC_CAPTURE_HALF_CB_ID :
htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; /* Legacy weak IC Capture half complete Callback */
break;
case HAL_TIM_OC_DELAY_ELAPSED_CB_ID :
htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; /* Legacy weak OC Delay Elapsed Callback */
break;
case HAL_TIM_PWM_PULSE_FINISHED_CB_ID :
htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; /* Legacy weak PWM Pulse Finished Callback */
break;
case HAL_TIM_PWM_PULSE_FINISHED_HALF_CB_ID :
htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; /* Legacy weak PWM Pulse Finished half complete Callback */
break;
case HAL_TIM_ERROR_CB_ID :
htim->ErrorCallback = HAL_TIM_ErrorCallback; /* Legacy weak Error Callback */
break;
case HAL_TIM_COMMUTATION_CB_ID :
htim->CommutationCallback = HAL_TIMEx_CommutCallback; /* Legacy weak Commutation Callback */
break;
case HAL_TIM_COMMUTATION_HALF_CB_ID :
htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; /* Legacy weak Commutation half complete Callback */
break;
case HAL_TIM_BREAK_CB_ID :
htim->BreakCallback = HAL_TIMEx_BreakCallback; /* Legacy weak Break Callback */
break;
default :
/* Return error status */
status = HAL_ERROR;
break;
}
}
else if (htim->State == HAL_TIM_STATE_RESET)
{
switch (CallbackID)
{
case HAL_TIM_BASE_MSPINIT_CB_ID :
htim->Base_MspInitCallback = HAL_TIM_Base_MspInit; /* Legacy weak Base MspInit Callback */
break;
case HAL_TIM_BASE_MSPDEINIT_CB_ID :
htim->Base_MspDeInitCallback = HAL_TIM_Base_MspDeInit; /* Legacy weak Base Msp DeInit Callback */
break;
case HAL_TIM_IC_MSPINIT_CB_ID :
htim->IC_MspInitCallback = HAL_TIM_IC_MspInit; /* Legacy weak IC Msp Init Callback */
break;
case HAL_TIM_IC_MSPDEINIT_CB_ID :
htim->IC_MspDeInitCallback = HAL_TIM_IC_MspDeInit; /* Legacy weak IC Msp DeInit Callback */
break;
case HAL_TIM_OC_MSPINIT_CB_ID :
htim->OC_MspInitCallback = HAL_TIM_OC_MspInit; /* Legacy weak OC Msp Init Callback */
break;
case HAL_TIM_OC_MSPDEINIT_CB_ID :
htim->OC_MspDeInitCallback = HAL_TIM_OC_MspDeInit; /* Legacy weak OC Msp DeInit Callback */
break;
case HAL_TIM_PWM_MSPINIT_CB_ID :
htim->PWM_MspInitCallback = HAL_TIM_PWM_MspInit; /* Legacy weak PWM Msp Init Callback */
break;
case HAL_TIM_PWM_MSPDEINIT_CB_ID :
htim->PWM_MspDeInitCallback = HAL_TIM_PWM_MspDeInit; /* Legacy weak PWM Msp DeInit Callback */
break;
case HAL_TIM_ONE_PULSE_MSPINIT_CB_ID :
htim->OnePulse_MspInitCallback = HAL_TIM_OnePulse_MspInit; /* Legacy weak One Pulse Msp Init Callback */
break;
case HAL_TIM_ONE_PULSE_MSPDEINIT_CB_ID :
htim->OnePulse_MspDeInitCallback = HAL_TIM_OnePulse_MspDeInit; /* Legacy weak One Pulse Msp DeInit Callback */
break;
case HAL_TIM_ENCODER_MSPINIT_CB_ID :
htim->Encoder_MspInitCallback = HAL_TIM_Encoder_MspInit; /* Legacy weak Encoder Msp Init Callback */
break;
case HAL_TIM_ENCODER_MSPDEINIT_CB_ID :
htim->Encoder_MspDeInitCallback = HAL_TIM_Encoder_MspDeInit; /* Legacy weak Encoder Msp DeInit Callback */
break;
case HAL_TIM_HALL_SENSOR_MSPINIT_CB_ID :
htim->HallSensor_MspInitCallback = HAL_TIMEx_HallSensor_MspInit; /* Legacy weak Hall Sensor Msp Init Callback */
break;
case HAL_TIM_HALL_SENSOR_MSPDEINIT_CB_ID :
htim->HallSensor_MspDeInitCallback = HAL_TIMEx_HallSensor_MspDeInit; /* Legacy weak Hall Sensor Msp DeInit Callback */
break;
default :
/* Return error status */
status = HAL_ERROR;
break;
}
}
else
{
/* Return error status */
status = HAL_ERROR;
}
/* Release Lock */
__HAL_UNLOCK(htim);
return status;
}
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
/**
* @}
*/
/** @defgroup TIM_Exported_Functions_Group10 TIM Peripheral State functions
* @brief TIM Peripheral State functions
*
@verbatim
==============================================================================
##### 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 Base handle state.
* @param htim TIM Base handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_Base_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @brief Return the TIM OC handle state.
* @param htim TIM Output Compare handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_OC_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @brief Return the TIM PWM handle state.
* @param htim TIM handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_PWM_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @brief Return the TIM Input Capture handle state.
* @param htim TIM IC handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_IC_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @brief Return the TIM One Pulse Mode handle state.
* @param htim TIM OPM handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_OnePulse_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @brief Return the TIM Encoder Mode handle state.
* @param htim TIM Encoder Interface handle
* @retval HAL state
*/
HAL_TIM_StateTypeDef HAL_TIM_Encoder_GetState(TIM_HandleTypeDef *htim)
{
return htim->State;
}
/**
* @}
*/
/**
* @}
*/
/** @defgroup TIM_Private_Functions TIM Private Functions
* @{
*/
/**
* @brief Time Base configuration
* @param TIMx TIM peripheral
* @param Structure TIM Base configuration structure
* @retval None
*/
void TIM_Base_SetConfig(TIM_TypeDef *TIMx, TIM_Base_InitTypeDef *Structure)
{
uint32_t tmpcr1;
tmpcr1 = TIMx->CR1;
/* Set TIM Time Base Unit parameters ---------------------------------------*/
if (IS_TIM_COUNTER_MODE_SELECT_INSTANCE(TIMx))
{
/* Select the Counter Mode */
tmpcr1 &= ~(TIM_CR1_DIR | TIM_CR1_CMS);
tmpcr1 |= Structure->CounterMode;
}
if (IS_TIM_CLOCK_DIVISION_INSTANCE(TIMx))
{
/* Set the clock division */
tmpcr1 &= ~TIM_CR1_CKD;
tmpcr1 |= (uint32_t)Structure->ClockDivision;
}
/* Set the auto-reload preload */
MODIFY_REG(tmpcr1, TIM_CR1_ARPE, Structure->AutoReloadPreload);
TIMx->CR1 = tmpcr1;
/* Set the Autoreload value */
TIMx->ARR = (uint32_t)Structure->Period ;
/* Set the Prescaler value */
TIMx->PSC = Structure->Prescaler;
if (IS_TIM_REPETITION_COUNTER_INSTANCE(TIMx))
{
/* Set the Repetition Counter value */
TIMx->RCR = Structure->RepetitionCounter;
}
/* Generate an update event to reload the Prescaler
and the repetition counter (only for advanced timer) value immediately */
TIMx->EGR = TIM_EGR_UG;
}
/**
* @brief Timer Output Compare 1 configuration
* @param TIMx to select the TIM peripheral
* @param OC_Config The ouput configuration structure
* @retval None
*/
static void TIM_OC1_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
{
uint32_t tmpccmrx;
uint32_t tmpccer;
uint32_t tmpcr2;
/* Disable the Channel 1: Reset the CC1E Bit */
TIMx->CCER &= ~TIM_CCER_CC1E;
/* Get the TIMx CCER register value */
tmpccer = TIMx->CCER;
/* Get the TIMx CR2 register value */
tmpcr2 = TIMx->CR2;
/* Get the TIMx CCMR1 register value */
tmpccmrx = TIMx->CCMR1;
/* Reset the Output Compare Mode Bits */
tmpccmrx &= ~TIM_CCMR1_OC1M;
tmpccmrx &= ~TIM_CCMR1_CC1S;
/* Select the Output Compare Mode */
tmpccmrx |= OC_Config->OCMode;
/* Reset the Output Polarity level */
tmpccer &= ~TIM_CCER_CC1P;
/* Set the Output Compare Polarity */
tmpccer |= OC_Config->OCPolarity;
if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_1))
{
/* Check parameters */
assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
/* Reset the Output N Polarity level */
tmpccer &= ~TIM_CCER_CC1NP;
/* Set the Output N Polarity */
tmpccer |= OC_Config->OCNPolarity;
/* Reset the Output N State */
tmpccer &= ~TIM_CCER_CC1NE;
}
if (IS_TIM_BREAK_INSTANCE(TIMx))
{
/* Check parameters */
assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
/* Reset the Output Compare and Output Compare N IDLE State */
tmpcr2 &= ~TIM_CR2_OIS1;
tmpcr2 &= ~TIM_CR2_OIS1N;
/* Set the Output Idle state */
tmpcr2 |= OC_Config->OCIdleState;
/* Set the Output N Idle state */
tmpcr2 |= OC_Config->OCNIdleState;
}
/* Write to TIMx CR2 */
TIMx->CR2 = tmpcr2;
/* Write to TIMx CCMR1 */
TIMx->CCMR1 = tmpccmrx;
/* Set the Capture Compare Register value */
TIMx->CCR1 = OC_Config->Pulse;
/* Write to TIMx CCER */
TIMx->CCER = tmpccer;
}
/**
* @brief Timer Output Compare 2 configuration
* @param TIMx to select the TIM peripheral
* @param OC_Config The ouput configuration structure
* @retval None
*/
void TIM_OC2_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
{
uint32_t tmpccmrx;
uint32_t tmpccer;
uint32_t tmpcr2;
/* Disable the Channel 2: Reset the CC2E Bit */
TIMx->CCER &= ~TIM_CCER_CC2E;
/* Get the TIMx CCER register value */
tmpccer = TIMx->CCER;
/* Get the TIMx CR2 register value */
tmpcr2 = TIMx->CR2;
/* Get the TIMx CCMR1 register value */
tmpccmrx = TIMx->CCMR1;
/* Reset the Output Compare mode and Capture/Compare selection Bits */
tmpccmrx &= ~TIM_CCMR1_OC2M;
tmpccmrx &= ~TIM_CCMR1_CC2S;
/* Select the Output Compare Mode */
tmpccmrx |= (OC_Config->OCMode << 8U);
/* Reset the Output Polarity level */
tmpccer &= ~TIM_CCER_CC2P;
/* Set the Output Compare Polarity */
tmpccer |= (OC_Config->OCPolarity << 4U);
if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_2))
{
assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
/* Reset the Output N Polarity level */
tmpccer &= ~TIM_CCER_CC2NP;
/* Set the Output N Polarity */
tmpccer |= (OC_Config->OCNPolarity << 4U);
/* Reset the Output N State */
tmpccer &= ~TIM_CCER_CC2NE;
}
if (IS_TIM_BREAK_INSTANCE(TIMx))
{
/* Check parameters */
assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
/* Reset the Output Compare and Output Compare N IDLE State */
tmpcr2 &= ~TIM_CR2_OIS2;
tmpcr2 &= ~TIM_CR2_OIS2N;
/* Set the Output Idle state */
tmpcr2 |= (OC_Config->OCIdleState << 2U);
/* Set the Output N Idle state */
tmpcr2 |= (OC_Config->OCNIdleState << 2U);
}
/* Write to TIMx CR2 */
TIMx->CR2 = tmpcr2;
/* Write to TIMx CCMR1 */
TIMx->CCMR1 = tmpccmrx;
/* Set the Capture Compare Register value */
TIMx->CCR2 = OC_Config->Pulse;
/* Write to TIMx CCER */
TIMx->CCER = tmpccer;
}
/**
* @brief Timer Output Compare 3 configuration
* @param TIMx to select the TIM peripheral
* @param OC_Config The ouput configuration structure
* @retval None
*/
static void TIM_OC3_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
{
uint32_t tmpccmrx;
uint32_t tmpccer;
uint32_t tmpcr2;
/* Disable the Channel 3: Reset the CC2E Bit */
TIMx->CCER &= ~TIM_CCER_CC3E;
/* Get the TIMx CCER register value */
tmpccer = TIMx->CCER;
/* Get the TIMx CR2 register value */
tmpcr2 = TIMx->CR2;
/* Get the TIMx CCMR2 register value */
tmpccmrx = TIMx->CCMR2;
/* Reset the Output Compare mode and Capture/Compare selection Bits */
tmpccmrx &= ~TIM_CCMR2_OC3M;
tmpccmrx &= ~TIM_CCMR2_CC3S;
/* Select the Output Compare Mode */
tmpccmrx |= OC_Config->OCMode;
/* Reset the Output Polarity level */
tmpccer &= ~TIM_CCER_CC3P;
/* Set the Output Compare Polarity */
tmpccer |= (OC_Config->OCPolarity << 8U);
if (IS_TIM_CCXN_INSTANCE(TIMx, TIM_CHANNEL_3))
{
assert_param(IS_TIM_OCN_POLARITY(OC_Config->OCNPolarity));
/* Reset the Output N Polarity level */
tmpccer &= ~TIM_CCER_CC3NP;
/* Set the Output N Polarity */
tmpccer |= (OC_Config->OCNPolarity << 8U);
/* Reset the Output N State */
tmpccer &= ~TIM_CCER_CC3NE;
}
if (IS_TIM_BREAK_INSTANCE(TIMx))
{
/* Check parameters */
assert_param(IS_TIM_OCNIDLE_STATE(OC_Config->OCNIdleState));
assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
/* Reset the Output Compare and Output Compare N IDLE State */
tmpcr2 &= ~TIM_CR2_OIS3;
tmpcr2 &= ~TIM_CR2_OIS3N;
/* Set the Output Idle state */
tmpcr2 |= (OC_Config->OCIdleState << 4U);
/* Set the Output N Idle state */
tmpcr2 |= (OC_Config->OCNIdleState << 4U);
}
/* Write to TIMx CR2 */
TIMx->CR2 = tmpcr2;
/* Write to TIMx CCMR2 */
TIMx->CCMR2 = tmpccmrx;
/* Set the Capture Compare Register value */
TIMx->CCR3 = OC_Config->Pulse;
/* Write to TIMx CCER */
TIMx->CCER = tmpccer;
}
/**
* @brief Timer Output Compare 4 configuration
* @param TIMx to select the TIM peripheral
* @param OC_Config The ouput configuration structure
* @retval None
*/
static void TIM_OC4_SetConfig(TIM_TypeDef *TIMx, TIM_OC_InitTypeDef *OC_Config)
{
uint32_t tmpccmrx;
uint32_t tmpccer;
uint32_t tmpcr2;
/* Disable the Channel 4: Reset the CC4E Bit */
TIMx->CCER &= ~TIM_CCER_CC4E;
/* Get the TIMx CCER register value */
tmpccer = TIMx->CCER;
/* Get the TIMx CR2 register value */
tmpcr2 = TIMx->CR2;
/* Get the TIMx CCMR2 register value */
tmpccmrx = TIMx->CCMR2;
/* Reset the Output Compare mode and Capture/Compare selection Bits */
tmpccmrx &= ~TIM_CCMR2_OC4M;
tmpccmrx &= ~TIM_CCMR2_CC4S;
/* Select the Output Compare Mode */
tmpccmrx |= (OC_Config->OCMode << 8U);
/* Reset the Output Polarity level */
tmpccer &= ~TIM_CCER_CC4P;
/* Set the Output Compare Polarity */
tmpccer |= (OC_Config->OCPolarity << 12U);
if (IS_TIM_BREAK_INSTANCE(TIMx))
{
/* Check parameters */
assert_param(IS_TIM_OCIDLE_STATE(OC_Config->OCIdleState));
/* Reset the Output Compare IDLE State */
tmpcr2 &= ~TIM_CR2_OIS4;
/* Set the Output Idle state */
tmpcr2 |= (OC_Config->OCIdleState << 6U);
}
/* Write to TIMx CR2 */
TIMx->CR2 = tmpcr2;
/* Write to TIMx CCMR2 */
TIMx->CCMR2 = tmpccmrx;
/* Set the Capture Compare Register value */
TIMx->CCR4 = OC_Config->Pulse;
/* Write to TIMx CCER */
TIMx->CCER = tmpccer;
}
/**
* @brief Slave Timer configuration function
* @param htim TIM handle
* @param sSlaveConfig Slave timer configuration
* @retval None
*/
static HAL_StatusTypeDef TIM_SlaveTimer_SetConfig(TIM_HandleTypeDef *htim,
TIM_SlaveConfigTypeDef *sSlaveConfig)
{
uint32_t tmpsmcr;
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Get the TIMx SMCR register value */
tmpsmcr = htim->Instance->SMCR;
/* Reset the Trigger Selection Bits */
tmpsmcr &= ~TIM_SMCR_TS;
/* Set the Input Trigger source */
tmpsmcr |= sSlaveConfig->InputTrigger;
/* Reset the slave mode Bits */
tmpsmcr &= ~TIM_SMCR_SMS;
/* Set the slave mode */
tmpsmcr |= sSlaveConfig->SlaveMode;
/* Write to TIMx SMCR */
htim->Instance->SMCR = tmpsmcr;
/* Configure the trigger prescaler, filter, and polarity */
switch (sSlaveConfig->InputTrigger)
{
case TIM_TS_ETRF:
{
/* Check the parameters */
assert_param(IS_TIM_CLOCKSOURCE_ETRMODE1_INSTANCE(htim->Instance));
assert_param(IS_TIM_TRIGGERPRESCALER(sSlaveConfig->TriggerPrescaler));
assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
/* Configure the ETR Trigger source */
TIM_ETR_SetConfig(htim->Instance,
sSlaveConfig->TriggerPrescaler,
sSlaveConfig->TriggerPolarity,
sSlaveConfig->TriggerFilter);
break;
}
case TIM_TS_TI1F_ED:
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
if(sSlaveConfig->SlaveMode == TIM_SLAVEMODE_GATED)
{
return HAL_ERROR;
}
/* Disable the Channel 1: Reset the CC1E Bit */
tmpccer = htim->Instance->CCER;
htim->Instance->CCER &= ~TIM_CCER_CC1E;
tmpccmr1 = htim->Instance->CCMR1;
/* Set the filter */
tmpccmr1 &= ~TIM_CCMR1_IC1F;
tmpccmr1 |= ((sSlaveConfig->TriggerFilter) << 4U);
/* Write to TIMx CCMR1 and CCER registers */
htim->Instance->CCMR1 = tmpccmr1;
htim->Instance->CCER = tmpccer;
break;
}
case TIM_TS_TI1FP1:
{
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(htim->Instance));
assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
/* Configure TI1 Filter and Polarity */
TIM_TI1_ConfigInputStage(htim->Instance,
sSlaveConfig->TriggerPolarity,
sSlaveConfig->TriggerFilter);
break;
}
case TIM_TS_TI2FP2:
{
/* Check the parameters */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
assert_param(IS_TIM_TRIGGERPOLARITY(sSlaveConfig->TriggerPolarity));
assert_param(IS_TIM_TRIGGERFILTER(sSlaveConfig->TriggerFilter));
/* Configure TI2 Filter and Polarity */
TIM_TI2_ConfigInputStage(htim->Instance,
sSlaveConfig->TriggerPolarity,
sSlaveConfig->TriggerFilter);
break;
}
case TIM_TS_ITR0:
case TIM_TS_ITR1:
case TIM_TS_ITR2:
case TIM_TS_ITR3:
{
/* Check the parameter */
assert_param(IS_TIM_CC2_INSTANCE(htim->Instance));
break;
}
default:
break;
}
return HAL_OK;
}
/**
* @brief Configure the TI1 as Input.
* @param TIMx to select the TIM peripheral.
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICSelection specifies the input to be used.
* This parameter can be one of the following values:
* @arg TIM_ICSELECTION_DIRECTTI: TIM Input 1 is selected to be connected to IC1.
* @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 1 is selected to be connected to IC2.
* @arg TIM_ICSELECTION_TRC: TIM Input 1 is selected to be connected to TRC.
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @retval None
* @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI2FP1
* (on channel2 path) is used as the input signal. Therefore CCMR1 must be
* protected against un-initialized filter and polarity values.
*/
void TIM_TI1_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter)
{
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Disable the Channel 1: Reset the CC1E Bit */
TIMx->CCER &= ~TIM_CCER_CC1E;
tmpccmr1 = TIMx->CCMR1;
tmpccer = TIMx->CCER;
/* Select the Input */
if (IS_TIM_CC2_INSTANCE(TIMx) != RESET)
{
tmpccmr1 &= ~TIM_CCMR1_CC1S;
tmpccmr1 |= TIM_ICSelection;
}
else
{
tmpccmr1 |= TIM_CCMR1_CC1S_0;
}
/* Set the filter */
tmpccmr1 &= ~TIM_CCMR1_IC1F;
tmpccmr1 |= ((TIM_ICFilter << 4U) & TIM_CCMR1_IC1F);
/* Select the Polarity and set the CC1E Bit */
tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
tmpccer |= (TIM_ICPolarity & (TIM_CCER_CC1P | TIM_CCER_CC1NP));
/* Write to TIMx CCMR1 and CCER registers */
TIMx->CCMR1 = tmpccmr1;
TIMx->CCER = tmpccer;
}
/**
* @brief Configure the Polarity and Filter for TI1.
* @param TIMx to select the TIM peripheral.
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @retval None
*/
static void TIM_TI1_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
{
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Disable the Channel 1: Reset the CC1E Bit */
tmpccer = TIMx->CCER;
TIMx->CCER &= ~TIM_CCER_CC1E;
tmpccmr1 = TIMx->CCMR1;
/* Set the filter */
tmpccmr1 &= ~TIM_CCMR1_IC1F;
tmpccmr1 |= (TIM_ICFilter << 4U);
/* Select the Polarity and set the CC1E Bit */
tmpccer &= ~(TIM_CCER_CC1P | TIM_CCER_CC1NP);
tmpccer |= TIM_ICPolarity;
/* Write to TIMx CCMR1 and CCER registers */
TIMx->CCMR1 = tmpccmr1;
TIMx->CCER = tmpccer;
}
/**
* @brief Configure the TI2 as Input.
* @param TIMx to select the TIM peripheral
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICSelection specifies the input to be used.
* This parameter can be one of the following values:
* @arg TIM_ICSELECTION_DIRECTTI: TIM Input 2 is selected to be connected to IC2.
* @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 2 is selected to be connected to IC1.
* @arg TIM_ICSELECTION_TRC: TIM Input 2 is selected to be connected to TRC.
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @retval None
* @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI1FP2
* (on channel1 path) is used as the input signal. Therefore CCMR1 must be
* protected against un-initialized filter and polarity values.
*/
static void TIM_TI2_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter)
{
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Disable the Channel 2: Reset the CC2E Bit */
TIMx->CCER &= ~TIM_CCER_CC2E;
tmpccmr1 = TIMx->CCMR1;
tmpccer = TIMx->CCER;
/* Select the Input */
tmpccmr1 &= ~TIM_CCMR1_CC2S;
tmpccmr1 |= (TIM_ICSelection << 8U);
/* Set the filter */
tmpccmr1 &= ~TIM_CCMR1_IC2F;
tmpccmr1 |= ((TIM_ICFilter << 12U) & TIM_CCMR1_IC2F);
/* Select the Polarity and set the CC2E Bit */
tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
tmpccer |= ((TIM_ICPolarity << 4U) & (TIM_CCER_CC2P | TIM_CCER_CC2NP));
/* Write to TIMx CCMR1 and CCER registers */
TIMx->CCMR1 = tmpccmr1 ;
TIMx->CCER = tmpccer;
}
/**
* @brief Configure the Polarity and Filter for TI2.
* @param TIMx to select the TIM peripheral.
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @retval None
*/
static void TIM_TI2_ConfigInputStage(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICFilter)
{
uint32_t tmpccmr1;
uint32_t tmpccer;
/* Disable the Channel 2: Reset the CC2E Bit */
TIMx->CCER &= ~TIM_CCER_CC2E;
tmpccmr1 = TIMx->CCMR1;
tmpccer = TIMx->CCER;
/* Set the filter */
tmpccmr1 &= ~TIM_CCMR1_IC2F;
tmpccmr1 |= (TIM_ICFilter << 12U);
/* Select the Polarity and set the CC2E Bit */
tmpccer &= ~(TIM_CCER_CC2P | TIM_CCER_CC2NP);
tmpccer |= (TIM_ICPolarity << 4U);
/* Write to TIMx CCMR1 and CCER registers */
TIMx->CCMR1 = tmpccmr1 ;
TIMx->CCER = tmpccer;
}
/**
* @brief Configure the TI3 as Input.
* @param TIMx to select the TIM peripheral
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICSelection specifies the input to be used.
* This parameter can be one of the following values:
* @arg TIM_ICSELECTION_DIRECTTI: TIM Input 3 is selected to be connected to IC3.
* @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 3 is selected to be connected to IC4.
* @arg TIM_ICSELECTION_TRC: TIM Input 3 is selected to be connected to TRC.
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @retval None
* @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI3FP4
* (on channel1 path) is used as the input signal. Therefore CCMR2 must be
* protected against un-initialized filter and polarity values.
*/
static void TIM_TI3_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter)
{
uint32_t tmpccmr2;
uint32_t tmpccer;
/* Disable the Channel 3: Reset the CC3E Bit */
TIMx->CCER &= ~TIM_CCER_CC3E;
tmpccmr2 = TIMx->CCMR2;
tmpccer = TIMx->CCER;
/* Select the Input */
tmpccmr2 &= ~TIM_CCMR2_CC3S;
tmpccmr2 |= TIM_ICSelection;
/* Set the filter */
tmpccmr2 &= ~TIM_CCMR2_IC3F;
tmpccmr2 |= ((TIM_ICFilter << 4U) & TIM_CCMR2_IC3F);
/* Select the Polarity and set the CC3E Bit */
tmpccer &= ~(TIM_CCER_CC3P | TIM_CCER_CC3NP);
tmpccer |= ((TIM_ICPolarity << 8U) & (TIM_CCER_CC3P | TIM_CCER_CC3NP));
/* Write to TIMx CCMR2 and CCER registers */
TIMx->CCMR2 = tmpccmr2;
TIMx->CCER = tmpccer;
}
/**
* @brief Configure the TI4 as Input.
* @param TIMx to select the TIM peripheral
* @param TIM_ICPolarity The Input Polarity.
* This parameter can be one of the following values:
* @arg TIM_ICPOLARITY_RISING
* @arg TIM_ICPOLARITY_FALLING
* @arg TIM_ICPOLARITY_BOTHEDGE
* @param TIM_ICSelection specifies the input to be used.
* This parameter can be one of the following values:
* @arg TIM_ICSELECTION_DIRECTTI: TIM Input 4 is selected to be connected to IC4.
* @arg TIM_ICSELECTION_INDIRECTTI: TIM Input 4 is selected to be connected to IC3.
* @arg TIM_ICSELECTION_TRC: TIM Input 4 is selected to be connected to TRC.
* @param TIM_ICFilter Specifies the Input Capture Filter.
* This parameter must be a value between 0x00 and 0x0F.
* @note TIM_ICFilter and TIM_ICPolarity are not used in INDIRECT mode as TI4FP3
* (on channel1 path) is used as the input signal. Therefore CCMR2 must be
* protected against un-initialized filter and polarity values.
* @retval None
*/
static void TIM_TI4_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ICPolarity, uint32_t TIM_ICSelection,
uint32_t TIM_ICFilter)
{
uint32_t tmpccmr2;
uint32_t tmpccer;
/* Disable the Channel 4: Reset the CC4E Bit */
TIMx->CCER &= ~TIM_CCER_CC4E;
tmpccmr2 = TIMx->CCMR2;
tmpccer = TIMx->CCER;
/* Select the Input */
tmpccmr2 &= ~TIM_CCMR2_CC4S;
tmpccmr2 |= (TIM_ICSelection << 8U);
/* Set the filter */
tmpccmr2 &= ~TIM_CCMR2_IC4F;
tmpccmr2 |= ((TIM_ICFilter << 12U) & TIM_CCMR2_IC4F);
/* Select the Polarity and set the CC4E Bit */
tmpccer &= ~(TIM_CCER_CC4P);
tmpccer |= ((TIM_ICPolarity << 12U) & (TIM_CCER_CC4P));
/* Write to TIMx CCMR2 and CCER registers */
TIMx->CCMR2 = tmpccmr2;
TIMx->CCER = tmpccer ;
}
/**
* @brief Selects the Input Trigger source
* @param TIMx to select the TIM peripheral
* @param InputTriggerSource The Input Trigger source.
* This parameter can be one of the following values:
* @arg TIM_TS_ITR0: Internal Trigger 0
* @arg TIM_TS_ITR1: Internal Trigger 1
* @arg TIM_TS_ITR2: Internal Trigger 2
* @arg TIM_TS_ITR3: Internal Trigger 3
* @arg TIM_TS_TI1F_ED: TI1 Edge Detector
* @arg TIM_TS_TI1FP1: Filtered Timer Input 1
* @arg TIM_TS_TI2FP2: Filtered Timer Input 2
* @arg TIM_TS_ETRF: External Trigger input
* @retval None
*/
static void TIM_ITRx_SetConfig(TIM_TypeDef *TIMx, uint32_t InputTriggerSource)
{
uint32_t tmpsmcr;
/* Get the TIMx SMCR register value */
tmpsmcr = TIMx->SMCR;
/* Reset the TS Bits */
tmpsmcr &= ~TIM_SMCR_TS;
/* Set the Input Trigger source and the slave mode*/
tmpsmcr |= (InputTriggerSource | TIM_SLAVEMODE_EXTERNAL1);
/* Write to TIMx SMCR */
TIMx->SMCR = tmpsmcr;
}
/**
* @brief Configures the TIMx External Trigger (ETR).
* @param TIMx to select the TIM peripheral
* @param TIM_ExtTRGPrescaler The external Trigger Prescaler.
* This parameter can be one of the following values:
* @arg TIM_ETRPRESCALER_DIV1: ETRP Prescaler OFF.
* @arg TIM_ETRPRESCALER_DIV2: ETRP frequency divided by 2.
* @arg TIM_ETRPRESCALER_DIV4: ETRP frequency divided by 4.
* @arg TIM_ETRPRESCALER_DIV8: ETRP frequency divided by 8.
* @param TIM_ExtTRGPolarity The external Trigger Polarity.
* This parameter can be one of the following values:
* @arg TIM_ETRPOLARITY_INVERTED: active low or falling edge active.
* @arg TIM_ETRPOLARITY_NONINVERTED: active high or rising edge active.
* @param ExtTRGFilter External Trigger Filter.
* This parameter must be a value between 0x00 and 0x0F
* @retval None
*/
void TIM_ETR_SetConfig(TIM_TypeDef *TIMx, uint32_t TIM_ExtTRGPrescaler,
uint32_t TIM_ExtTRGPolarity, uint32_t ExtTRGFilter)
{
uint32_t tmpsmcr;
tmpsmcr = TIMx->SMCR;
/* Reset the ETR Bits */
tmpsmcr &= ~(TIM_SMCR_ETF | TIM_SMCR_ETPS | TIM_SMCR_ECE | TIM_SMCR_ETP);
/* Set the Prescaler, the Filter value and the Polarity */
tmpsmcr |= (uint32_t)(TIM_ExtTRGPrescaler | (TIM_ExtTRGPolarity | (ExtTRGFilter << 8U)));
/* Write to TIMx SMCR */
TIMx->SMCR = tmpsmcr;
}
/**
* @brief Enables or disables the TIM Capture Compare Channel x.
* @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
* @arg TIM_CHANNEL_4: TIM Channel 4
* @param ChannelState specifies the TIM Channel CCxE bit new state.
* This parameter can be: TIM_CCx_ENABLE or TIM_CCx_DISABLE.
* @retval None
*/
void TIM_CCxChannelCmd(TIM_TypeDef *TIMx, uint32_t Channel, uint32_t ChannelState)
{
uint32_t tmp;
/* Check the parameters */
assert_param(IS_TIM_CC1_INSTANCE(TIMx));
assert_param(IS_TIM_CHANNELS(Channel));
tmp = TIM_CCER_CC1E << (Channel & 0x1FU); /* 0x1FU = 31 bits max shift */
/* Reset the CCxE Bit */
TIMx->CCER &= ~tmp;
/* Set or reset the CCxE Bit */
TIMx->CCER |= (uint32_t)(ChannelState << (Channel & 0x1FU)); /* 0x1FU = 31 bits max shift */
}
#if (USE_HAL_TIM_REGISTER_CALLBACKS == 1)
/**
* @brief Reset interrupt callbacks to the legacy weak callbacks.
* @param htim pointer to a TIM_HandleTypeDef structure that contains
* the configuration information for TIM module.
* @retval None
*/
void TIM_ResetCallback(TIM_HandleTypeDef *htim)
{
/* Reset the TIM callback to the legacy weak callbacks */
htim->PeriodElapsedCallback = HAL_TIM_PeriodElapsedCallback; /* Legacy weak PeriodElapsedCallback */
htim->PeriodElapsedHalfCpltCallback = HAL_TIM_PeriodElapsedHalfCpltCallback; /* Legacy weak PeriodElapsedHalfCpltCallback */
htim->TriggerCallback = HAL_TIM_TriggerCallback; /* Legacy weak TriggerCallback */
htim->TriggerHalfCpltCallback = HAL_TIM_TriggerHalfCpltCallback; /* Legacy weak TriggerHalfCpltCallback */
htim->IC_CaptureCallback = HAL_TIM_IC_CaptureCallback; /* Legacy weak IC_CaptureCallback */
htim->IC_CaptureHalfCpltCallback = HAL_TIM_IC_CaptureHalfCpltCallback; /* Legacy weak IC_CaptureHalfCpltCallback */
htim->OC_DelayElapsedCallback = HAL_TIM_OC_DelayElapsedCallback; /* Legacy weak OC_DelayElapsedCallback */
htim->PWM_PulseFinishedCallback = HAL_TIM_PWM_PulseFinishedCallback; /* Legacy weak PWM_PulseFinishedCallback */
htim->PWM_PulseFinishedHalfCpltCallback = HAL_TIM_PWM_PulseFinishedHalfCpltCallback; /* Legacy weak PWM_PulseFinishedHalfCpltCallback */
htim->ErrorCallback = HAL_TIM_ErrorCallback; /* Legacy weak ErrorCallback */
htim->CommutationCallback = HAL_TIMEx_CommutCallback; /* Legacy weak CommutationCallback */
htim->CommutationHalfCpltCallback = HAL_TIMEx_CommutHalfCpltCallback; /* Legacy weak CommutationHalfCpltCallback */
htim->BreakCallback = HAL_TIMEx_BreakCallback; /* Legacy weak BreakCallback */
}
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
/**
* @}
*/
#endif /* HAL_TIM_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,1959 @@
/**
******************************************************************************
* @file py32f002b_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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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****/

View File

@@ -0,0 +1,2141 @@
/**
******************************************************************************
* @file py32f002b_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.
(#) 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
*** 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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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);
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 */
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
, 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.
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()
(#) 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.
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;
}
}
/**
* @brief Abort ongoing transfers (blocking mode).
* @param huart UART handle.
* @note This procedure could be used for aborting any ongoing transfer started in Interrupt mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx and Rx)
* - 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_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);
/* 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 mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx)
* - 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_UART_AbortTransmit(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
/* 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 mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Rx)
* - 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_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);
/* 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 mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx and Rx)
* - 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_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);
/* 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;
/* 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 mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Tx)
* - 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_UART_AbortTransmit_IT(UART_HandleTypeDef *huart)
{
/* Disable TXEIE and TCIE interrupts */
CLEAR_BIT(huart->Instance->CR1, (USART_CR1_TXEIE | USART_CR1_TCIE));
/* Reset Tx transfer counter */
huart->TxXferCount = 0x00U;
/* Restore huart->gState to Ready */
huart->gState = HAL_UART_STATE_READY;
/* 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 */
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 mode.
* This procedure performs following operations :
* - Disable UART Interrupts (Rx)
* - 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_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);
/* Reset Rx transfer counter */
huart->RxXferCount = 0x00U;
/* Restore huart->RxState to Ready */
huart->RxState = HAL_UART_STATE_READY;
/* 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 */
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.
* @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 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,
consider error as blocking */
if ((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET)
{
/* Blocking error : transfer is aborted
Set the UART state ready to be able to start again the process,
Disable Rx Interrupts, if ongoing */
UART_EndRxTransfer(huart);
/* 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
{
/* 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 */
/* Idle frame detect */
if (((isrflags & USART_SR_IDLE) != RESET) && ((cr1its & USART_CR1_IDLEIE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
HAL_UART_IdleFrameDetectCpltCallback(huart);
}
/* 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.
*/
}
/**
* @brief UART Idle Frame Detect Complete callback.
* @param huart UART handle.
* @retval None
*/
__weak void HAL_UART_IdleFrameDetectCpltCallback(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_IdleFrameDetectCpltCallback 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_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 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 */
/**
* @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;
}
/**
* @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;
}
/**
* @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****/

View File

@@ -0,0 +1,1932 @@
/**
******************************************************************************
* @file py32f002b_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.
(#) 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
*** 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>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 PY32F002B_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);
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
, 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.
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()
(#) 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.
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;
}
}
/**
* @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 mode.
* This procedure performs following operations :
* - Disable PPP Interrupts (depending of transfer direction)
* - 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_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);
/* 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 mode.
* This procedure performs following operations :
* - Disable PPP Interrupts (depending of transfer direction)
* - 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_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);
/* 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;
/* 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.
* @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 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,
consider error as blocking */
if ((husart->ErrorCode & HAL_USART_ERROR_ORE) != RESET)
{
/* Set the USART state ready to be able to start again the process,
Disable Rx Interrupts, if ongoing */
USART_EndRxTransfer(husart);
/* 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
{
/* 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 */
/**
* @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;
}
/**
* @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;
}
/**
* @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****/

View File

@@ -0,0 +1,508 @@
/**
******************************************************************************
* @file py32f002b_ll_adc.c
* @author MCU Application Team
* @brief ADC LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_adc.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "PY32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_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) \
)
#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) \
)
#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);
}
}
/* 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;
}
}
/* Disable the ADC instance */
LL_ADC_Disable(ADCx);
/* Wait for ADC instance is effectively disabled */
timeout_cpu_cycles = ADC_TIMEOUT_DISABLE_CPU_CYCLES;
while (LL_ADC_IsDisableOngoing(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_ADDIS | 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_VREFBUFF_SEL, ADC_CR_VREF_BUFFERE */
CLEAR_BIT(ADCx->CR,(ADC_CR_VREFBUFF_SEL | ADC_CR_VREF_BUFFERE) );
/* Reset register CFGR1 */
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 )
);
/* 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 */
#if defined(ADC_CHSELR_CHSEL10)
CLEAR_BIT(ADCx->CHSELR,
( ADC_CHSELR_CHSEL10 | 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 )
);
#else
CLEAR_BIT(ADCx->CHSELR,
( 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 )
);
#endif
/* 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. */
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 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 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));
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 overrun behavior */
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
);
}
else
{
/* Initialization error: ADC instance is not disabled. */
status = ERROR;
}
return status;
}
/**
* @brief Set each @ref LL_ADC_REG_InitTypeDef field to default value.
* @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 */
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;
ADC_REG_InitStruct->Overrun = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* ADC1 */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,198 @@
/**
******************************************************************************
* @file py32f002b_ll_comp.c
* @author MCU Application Team
* @brief COMP LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_comp.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32002B_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_INPUT_PLUS(__COMP_INSTANCE__, __INPUT_PLUS__) \
( ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO1) \
|| ((__INPUT_PLUS__) == LL_COMP_INPUT_PLUS_IO2) \
)
#define IS_LL_COMP_INPUT_MINUS(__COMP_INSTANCE__, __INPUT_MINUS__) \
( ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO1) \
|| ((__INPUT_MINUS__) == LL_COMP_INPUT_MINUS_IO2) \
)
#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));
LL_COMP_WriteReg(COMPx, CSR, 0x00000000U);
LL_COMP_WriteReg(COMPx, FR, 0x00000000U);
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_INPUT_PLUS(COMPx, COMP_InitStruct->InputPlus));
assert_param(IS_LL_COMP_INPUT_MINUS(COMPx, COMP_InitStruct->InputMinus));
assert_param(IS_LL_COMP_OUTPUT_POLARITY(COMP_InitStruct->OutputPolarity));
/* Configuration of comparator instance : */
/* - InputPlus */
/* - InputMinus */
/* - OutputPolarity */
MODIFY_REG(COMPx->CSR,
COMP_CSR_INPSEL
| COMP_CSR_INNSEL
| COMP_CSR_POLARITY
,
COMP_InitStruct->InputPlus
| COMP_InitStruct->InputMinus
| COMP_InitStruct->OutputPolarity
);
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)));
}
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->InputPlus = LL_COMP_INPUT_PLUS_IO1;
COMP_InitStruct->InputMinus = LL_COMP_INPUT_MINUS_IO1;
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****/

View File

@@ -0,0 +1,111 @@
/**
******************************************************************************
* @file py32f002b_ll_crc.c
* @author MCU Application Team
* @brief CRC LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_crc.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_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****/

View File

@@ -0,0 +1,228 @@
/**
******************************************************************************
* @file py32f002b_ll_exti.c
* @author MCU Application Team
* @brief EXTI LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_exti.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32F002B_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_17 ) || \
(__VALUE__ == LL_EXTI_LINE_18 ) || \
(__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, 0x20000000U);
/* 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, 0x0000600FFU);
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****/

View File

@@ -0,0 +1,253 @@
/**
******************************************************************************
* @file py32f002b_ll_gpio.c
* @author MCU Application Team
* @brief GPIO LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_gpio.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
#if defined (GPIOA) || defined (GPIOB) || defined (GPIOC)
/** @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 ))
/**
* @}
*/
/* 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 == GPIOC)
{
LL_IOP_GRP1_ForceReset(LL_IOP_GRP1_PERIPH_GPIOC);
LL_IOP_GRP1_ReleaseReset(LL_IOP_GRP1_PERIPH_GPIOC);
}
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 (GPIOC) */
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya Semiconductor *****END OF FILE****/

View File

@@ -0,0 +1,194 @@
/**
******************************************************************************
* @file py32f002b_ll_i2c.c
* @author MCU Application Team
* @brief I2C LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_i2c.h"
#include "py32f002b_ll_bus.h"
#include "py32f002b_ll_rcc.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
#if defined (I2C1)
/** @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 */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,183 @@
/**
******************************************************************************
* @file py32f002b_ll_lptim.c
* @author MCU Application Team
* @brief LPTIM LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_lptim.h"
#include "py32f002b_ll_bus.h"
#include "py32f002b_ll_rcc.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32F002B_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****/

View File

@@ -0,0 +1,88 @@
/**
******************************************************************************
* @file py32f002b_ll_pwr.c
* @author MCU Application Team
* @brief PWR LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_pwr.h"
#include "py32f002b_ll_bus.h"
/** @addtogroup PY32F002B_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****/

View File

@@ -0,0 +1,433 @@
/**
******************************************************************************
* @file py32f002b_ll_rcc.c
* @author MCU Application Team
* @brief RCC LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_rcc.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_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);
/**
* @}
*/
/* 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
* - 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 and LSE clocks
* @retval An ErrorStatus enumeration value:
* - SUCCESS: RCC registers are de-initialized
* - ERROR: not applicable
*/
ErrorStatus LL_RCC_DeInit(void)
{
/* Set HSI_FS, HSITRIM bits to default value*/
LL_RCC_HSI_SetCalibFreq(LL_RCC_HSICALIBRATION_24MHz);
/* Set HSION bit and wait for HSI READY bit */
LL_RCC_HSI_Enable();
while (LL_RCC_HSI_IsReady() != 1U)
{}
/* 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);
/* 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(***)
* 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 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_IsBypass() == 1U)
{
mco_frequency = HSE_VALUE;
}
break;
case LL_RCC_MCO1SOURCE_LSI: /* MCO Clock is LSI */
if (LL_RCC_LSI_IsReady() == 1U)
{
mco_frequency = LL_RCC_LSI_GetFreq();
}
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 = LL_RCC_LSI_GetFreq();
}
break;
}
return lsc_frequency;
#else
return LL_RCC_LSI_GetFreq();
#endif
}
#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
* @arg @ref LL_RCC_COMP2_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 = LL_RCC_LSI_GetFreq();
}
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;
}
/**
* @}
*/
/**
* @}
*/
/** @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;
case LL_RCC_SYS_CLKSOURCE_STATUS_LSI:
frequency = LL_RCC_LSI_GetFreq();
#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());
}
/**
* @}
*/
#endif /* defined(RCC) */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya*****END OF FILE****/

View File

@@ -0,0 +1,284 @@
/**
******************************************************************************
* @file py32f002b_ll_spi.c
* @author MCU Application Team
* @brief SPI LL module driver.
******************************************************************************
Additional table :
DataSize = SPI_DATASIZE_8BIT:
+----------------------------------------------------------------------------------------------+
| | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
| Process | Tranfert mode |---------------------|----------------------|----------------------|
| | | Master | Slave | Master | Slave | Master | Slave |
|==============================================================================================|
| TX | Polling | Fpclk/2 | Fpclk/32 | NA | NA | NA | NA |
| / |----------------|----------|----------|-----------|----------|-----------|----------|
| RX | Interrupt | Fpclk/2 | Fpclk/32 | NA | NA | NA | NA |
| |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | NA | NA | Fpclk/4 | Fpclk/8 | Fpclk/4 | Fpclk/8 |
| R |----------------|----------|----------|-----------|----------|-----------|----------|
| X | Interrupt | NA | NA | Fpclk/16 | Fpclk/16 | Fpclk/16 | Fpclk/16 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | NA | NA | NA | NA | Fpclk/2 | Fpclk/8 |
| T |----------------|----------|----------|-----------|----------|-----------|----------|
| X | Interrupt | NA | NA | NA | NA | Fpclk/2 | Fpclk/16 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
+----------------------------------------------------------------------------------------------+
DataSize = SPI_DATASIZE_16BIT:
+----------------------------------------------------------------------------------------------+
| | | 2Lines Fullduplex | 2Lines RxOnly | 1Line |
| Process | Tranfert mode |---------------------|----------------------|----------------------|
| | | Master | Slave | Master | Slave | Master | Slave |
|==============================================================================================|
| TX | Polling | Fpclk/2 | Fpclk/16 | NA | NA | NA | NA |
| / |----------------|----------|----------|-----------|----------|-----------|----------|
| RX | Interrupt | Fpclk/2 | Fpclk/16 | NA | NA | NA | NA |
| |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | NA | NA | Fpclk/2 | Fpclk/4 | Fpclk/2 | Fpclk/4 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
| R | Interrupt | NA | NA | Fpclk/2 | Fpclk/8 | Fpclk/2 | Fpclk/8 |
| X |----------------|----------|----------|-----------|----------|-----------|----------|
|=========|================|==========|==========|===========|==========|===========|==========|
| | Polling | NA | NA | NA | NA | Fpclk/2 | Fpclk/4 |
| |----------------|----------|----------|-----------|----------|-----------|----------|
| T | Interrupt | NA | NA | NA | NA | Fpclk/2 | Fpclk/8 |
| X |----------------|----------|----------|-----------|----------|-----------|----------|
+----------------------------------------------------------------------------------------------+
@note The max SPI frequency depend on SPI data size (8bits, 16bits),
SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT).
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_spi.h"
#include "py32f002b_ll_bus.h"
#include "py32f002b_ll_rcc.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
#if defined (SPI1)
/** @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_DFF | \
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))
/**
* @}
*/
/* 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;
}
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));
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
* - DataWidth: SPI_CR1_DFF 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 | SPI_InitStruct->DataWidth);
/*---------------------------- SPIx CR2 Configuration ------------------------
* Configure SPIx CR2 with parameters:
* - NSS management: SSOE bit
*/
MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, ((SPI_InitStruct->NSS >> 16U) & SPI_CR2_SSOE));
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;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#endif /* defined (SPI1) */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,1201 @@
/**
******************************************************************************
* @file py32f002b_ll_tim.c
* @author MCU Application Team
* @brief TIM LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_tim.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32F002B_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_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****/

View File

@@ -0,0 +1,378 @@
/**
******************************************************************************
* @file py32f002b_ll_usart.c
* @author MCU Application Team
* @brief USART LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_usart.h"
#include "py32f002b_ll_rcc.h"
#include "py32f002b_ll_bus.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
#if defined (USART1)
/** @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);
}
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 */
/**
* @}
*/
#endif /* USE_FULL_LL_DRIVER */
/************************ (C) COPYRIGHT Puya *****END OF FILE****/

View File

@@ -0,0 +1,229 @@
/**
******************************************************************************
* @file py32f002b_ll_utils.c
* @author MCU Application Team
* @brief UTILS LL module driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) Puya Semiconductor Co.
* All rights reserved.</center></h2>
*
* <h2><center>&copy; 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 "py32f002b_ll_utils.h"
#include "py32f002b_ll_rcc.h"
#include "py32f002b_ll_system.h"
#ifdef USE_FULL_ASSERT
#include "py32_assert.h"
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
/** @addtogroup PY32F002B_LL_Driver
* @{
*/
/** @addtogroup UTILS_LL
* @{
*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private constants ---------------------------------------------------------*/
/** @addtogroup UTILS_LL_Private_Constants
* @{
*/
/* 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))
/**
* @}
*/
/* 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 --;
}
}
}
/**
* @}
*/
/**
* @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;
}
/**
* @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;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT Puya *****END OF FILE****/