initial
This commit is contained in:
379
system/src/cmsis/startup_stm32f103xb.S
Normal file
379
system/src/cmsis/startup_stm32f103xb.S
Normal file
@ -0,0 +1,379 @@
|
||||
/**
|
||||
*************** (C) COPYRIGHT 2016 STMicroelectronics ************************
|
||||
* @file startup_stm32f103xb.s
|
||||
* @author MCD Application Team
|
||||
* @version V4.1.0
|
||||
* @date 29-April-2016
|
||||
* @brief STM32F103xB Devices vector table for Atollic toolchain.
|
||||
* This module performs:
|
||||
* - Set the initial SP
|
||||
* - Set the initial PC == Reset_Handler,
|
||||
* - Set the vector table entries with the exceptions ISR address
|
||||
* - Configure the clock system
|
||||
* - Branches to main in the C library (which eventually
|
||||
* calls main()).
|
||||
* After Reset the Cortex-M3 processor is in Thread mode,
|
||||
* priority is Privileged, and the Stack is set to Main.
|
||||
******************************************************************************
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
.syntax unified
|
||||
.cpu cortex-m3
|
||||
.fpu softvfp
|
||||
.thumb
|
||||
|
||||
.global g_pfnVectors
|
||||
.global Default_Handler
|
||||
|
||||
/* start address for the initialization values of the .data section.
|
||||
defined in linker script */
|
||||
.word _sidata
|
||||
/* start address for the .data section. defined in linker script */
|
||||
.word _sdata
|
||||
/* end address for the .data section. defined in linker script */
|
||||
.word _edata
|
||||
/* start address for the .bss section. defined in linker script */
|
||||
.word _sbss
|
||||
/* end address for the .bss section. defined in linker script */
|
||||
.word _ebss
|
||||
|
||||
.equ BootRAM, 0xF108F85F
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor first
|
||||
* starts execution following a reset event. Only the absolutely
|
||||
* necessary set is performed, after which the application
|
||||
* supplied main() routine is called.
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
|
||||
.section .text.Reset_Handler
|
||||
.weak Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
|
||||
/* Copy the data segment initializers from flash to SRAM */
|
||||
movs r1, #0
|
||||
b LoopCopyDataInit
|
||||
|
||||
CopyDataInit:
|
||||
ldr r3, =_sidata
|
||||
ldr r3, [r3, r1]
|
||||
str r3, [r0, r1]
|
||||
adds r1, r1, #4
|
||||
|
||||
LoopCopyDataInit:
|
||||
ldr r0, =_sdata
|
||||
ldr r3, =_edata
|
||||
adds r2, r0, r1
|
||||
cmp r2, r3
|
||||
bcc CopyDataInit
|
||||
ldr r2, =_sbss
|
||||
b LoopFillZerobss
|
||||
/* Zero fill the bss segment. */
|
||||
FillZerobss:
|
||||
movs r3, #0
|
||||
str r3, [r2], #4
|
||||
|
||||
LoopFillZerobss:
|
||||
ldr r3, = _ebss
|
||||
cmp r2, r3
|
||||
bcc FillZerobss
|
||||
|
||||
/* Call the clock system intitialization function.*/
|
||||
bl SystemInit
|
||||
/* Call static constructors */
|
||||
bl __libc_init_array
|
||||
/* Call the application's entry point.*/
|
||||
bl main
|
||||
bx lr
|
||||
.size Reset_Handler, .-Reset_Handler
|
||||
|
||||
/**
|
||||
* @brief This is the code that gets called when the processor receives an
|
||||
* unexpected interrupt. This simply enters an infinite loop, preserving
|
||||
* the system state for examination by a debugger.
|
||||
*
|
||||
* @param None
|
||||
* @retval : None
|
||||
*/
|
||||
.section .text.Default_Handler,"ax",%progbits
|
||||
Default_Handler:
|
||||
Infinite_Loop:
|
||||
b Infinite_Loop
|
||||
.size Default_Handler, .-Default_Handler
|
||||
/******************************************************************************
|
||||
*
|
||||
* The minimal vector table for a Cortex M3. Note that the proper constructs
|
||||
* must be placed on this to ensure that it ends up at physical address
|
||||
* 0x0000.0000.
|
||||
*
|
||||
******************************************************************************/
|
||||
.section .isr_vector,"a",%progbits
|
||||
.type g_pfnVectors, %object
|
||||
.size g_pfnVectors, .-g_pfnVectors
|
||||
|
||||
|
||||
g_pfnVectors:
|
||||
|
||||
.word _estack
|
||||
.word Reset_Handler
|
||||
.word NMI_Handler
|
||||
.word HardFault_Handler
|
||||
.word MemManage_Handler
|
||||
.word BusFault_Handler
|
||||
.word UsageFault_Handler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word SVC_Handler
|
||||
.word DebugMon_Handler
|
||||
.word 0
|
||||
.word PendSV_Handler
|
||||
.word SysTick_Handler
|
||||
.word WWDG_IRQHandler
|
||||
.word PVD_IRQHandler
|
||||
.word TAMPER_IRQHandler
|
||||
.word RTC_IRQHandler
|
||||
.word FLASH_IRQHandler
|
||||
.word RCC_IRQHandler
|
||||
.word EXTI0_IRQHandler
|
||||
.word EXTI1_IRQHandler
|
||||
.word EXTI2_IRQHandler
|
||||
.word EXTI3_IRQHandler
|
||||
.word EXTI4_IRQHandler
|
||||
.word DMA1_Channel1_IRQHandler
|
||||
.word DMA1_Channel2_IRQHandler
|
||||
.word DMA1_Channel3_IRQHandler
|
||||
.word DMA1_Channel4_IRQHandler
|
||||
.word DMA1_Channel5_IRQHandler
|
||||
.word DMA1_Channel6_IRQHandler
|
||||
.word DMA1_Channel7_IRQHandler
|
||||
.word ADC1_2_IRQHandler
|
||||
.word USB_HP_CAN1_TX_IRQHandler
|
||||
.word USB_LP_CAN1_RX0_IRQHandler
|
||||
.word CAN1_RX1_IRQHandler
|
||||
.word CAN1_SCE_IRQHandler
|
||||
.word EXTI9_5_IRQHandler
|
||||
.word TIM1_BRK_IRQHandler
|
||||
.word TIM1_UP_IRQHandler
|
||||
.word TIM1_TRG_COM_IRQHandler
|
||||
.word TIM1_CC_IRQHandler
|
||||
.word TIM2_IRQHandler
|
||||
.word TIM3_IRQHandler
|
||||
.word TIM4_IRQHandler
|
||||
.word I2C1_EV_IRQHandler
|
||||
.word I2C1_ER_IRQHandler
|
||||
.word I2C2_EV_IRQHandler
|
||||
.word I2C2_ER_IRQHandler
|
||||
.word SPI1_IRQHandler
|
||||
.word SPI2_IRQHandler
|
||||
.word USART1_IRQHandler
|
||||
.word USART2_IRQHandler
|
||||
.word USART3_IRQHandler
|
||||
.word EXTI15_10_IRQHandler
|
||||
.word RTC_Alarm_IRQHandler
|
||||
.word USBWakeUp_IRQHandler
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word 0
|
||||
.word BootRAM /* @0x108. This is for boot in RAM mode for
|
||||
STM32F10x Medium Density devices. */
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Provide weak aliases for each Exception handler to the Default_Handler.
|
||||
* As they are weak aliases, any function with the same name will override
|
||||
* this definition.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
.weak NMI_Handler
|
||||
.thumb_set NMI_Handler,Default_Handler
|
||||
|
||||
.weak HardFault_Handler
|
||||
.thumb_set HardFault_Handler,Default_Handler
|
||||
|
||||
.weak MemManage_Handler
|
||||
.thumb_set MemManage_Handler,Default_Handler
|
||||
|
||||
.weak BusFault_Handler
|
||||
.thumb_set BusFault_Handler,Default_Handler
|
||||
|
||||
.weak UsageFault_Handler
|
||||
.thumb_set UsageFault_Handler,Default_Handler
|
||||
|
||||
.weak SVC_Handler
|
||||
.thumb_set SVC_Handler,Default_Handler
|
||||
|
||||
.weak DebugMon_Handler
|
||||
.thumb_set DebugMon_Handler,Default_Handler
|
||||
|
||||
.weak PendSV_Handler
|
||||
.thumb_set PendSV_Handler,Default_Handler
|
||||
|
||||
.weak SysTick_Handler
|
||||
.thumb_set SysTick_Handler,Default_Handler
|
||||
|
||||
.weak WWDG_IRQHandler
|
||||
.thumb_set WWDG_IRQHandler,Default_Handler
|
||||
|
||||
.weak PVD_IRQHandler
|
||||
.thumb_set PVD_IRQHandler,Default_Handler
|
||||
|
||||
.weak TAMPER_IRQHandler
|
||||
.thumb_set TAMPER_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_IRQHandler
|
||||
.thumb_set RTC_IRQHandler,Default_Handler
|
||||
|
||||
.weak FLASH_IRQHandler
|
||||
.thumb_set FLASH_IRQHandler,Default_Handler
|
||||
|
||||
.weak RCC_IRQHandler
|
||||
.thumb_set RCC_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI0_IRQHandler
|
||||
.thumb_set EXTI0_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI1_IRQHandler
|
||||
.thumb_set EXTI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI2_IRQHandler
|
||||
.thumb_set EXTI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI3_IRQHandler
|
||||
.thumb_set EXTI3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI4_IRQHandler
|
||||
.thumb_set EXTI4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel1_IRQHandler
|
||||
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel2_IRQHandler
|
||||
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel3_IRQHandler
|
||||
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel4_IRQHandler
|
||||
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel5_IRQHandler
|
||||
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel6_IRQHandler
|
||||
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
|
||||
|
||||
.weak DMA1_Channel7_IRQHandler
|
||||
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
|
||||
|
||||
.weak ADC1_2_IRQHandler
|
||||
.thumb_set ADC1_2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USB_HP_CAN1_TX_IRQHandler
|
||||
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
|
||||
|
||||
.weak USB_LP_CAN1_RX0_IRQHandler
|
||||
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_RX1_IRQHandler
|
||||
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
|
||||
|
||||
.weak CAN1_SCE_IRQHandler
|
||||
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI9_5_IRQHandler
|
||||
.thumb_set EXTI9_5_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_BRK_IRQHandler
|
||||
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_UP_IRQHandler
|
||||
.thumb_set TIM1_UP_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_TRG_COM_IRQHandler
|
||||
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM1_CC_IRQHandler
|
||||
.thumb_set TIM1_CC_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM2_IRQHandler
|
||||
.thumb_set TIM2_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM3_IRQHandler
|
||||
.thumb_set TIM3_IRQHandler,Default_Handler
|
||||
|
||||
.weak TIM4_IRQHandler
|
||||
.thumb_set TIM4_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_EV_IRQHandler
|
||||
.thumb_set I2C1_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C1_ER_IRQHandler
|
||||
.thumb_set I2C1_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_EV_IRQHandler
|
||||
.thumb_set I2C2_EV_IRQHandler,Default_Handler
|
||||
|
||||
.weak I2C2_ER_IRQHandler
|
||||
.thumb_set I2C2_ER_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI1_IRQHandler
|
||||
.thumb_set SPI1_IRQHandler,Default_Handler
|
||||
|
||||
.weak SPI2_IRQHandler
|
||||
.thumb_set SPI2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART1_IRQHandler
|
||||
.thumb_set USART1_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART2_IRQHandler
|
||||
.thumb_set USART2_IRQHandler,Default_Handler
|
||||
|
||||
.weak USART3_IRQHandler
|
||||
.thumb_set USART3_IRQHandler,Default_Handler
|
||||
|
||||
.weak EXTI15_10_IRQHandler
|
||||
.thumb_set EXTI15_10_IRQHandler,Default_Handler
|
||||
|
||||
.weak RTC_Alarm_IRQHandler
|
||||
.thumb_set RTC_Alarm_IRQHandler,Default_Handler
|
||||
|
||||
.weak USBWakeUp_IRQHandler
|
||||
.thumb_set USBWakeUp_IRQHandler,Default_Handler
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
448
system/src/cmsis/system_stm32f1xx.c
Normal file
448
system/src/cmsis/system_stm32f1xx.c
Normal file
@ -0,0 +1,448 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f1xx.c
|
||||
* @author MCD Application Team
|
||||
* @version V4.1.0
|
||||
* @date 29-April-2016
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||
* factors, AHB/APBx prescalers and Flash settings).
|
||||
* This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f1xx_xx.s" file.
|
||||
*
|
||||
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
|
||||
* by the user application to setup the SysTick
|
||||
* timer or configure other parameters.
|
||||
*
|
||||
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
|
||||
* be called whenever the core clock is changed
|
||||
* during program execution.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||
* the product used), refer to "HSE_VALUE".
|
||||
* When HSE is used as system clock source, directly or through PLL, and you
|
||||
* are using different crystal you have to adapt the HSE value to your own
|
||||
* configuration.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @addtogroup CMSIS
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup stm32f1xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE ((uint32_t)8000000) /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/*!< Uncomment the following line if you need to use external SRAM */
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/*!< Uncomment the following line if you need to relocate your vector Table in
|
||||
Internal SRAM. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* Clock Definitions
|
||||
*******************************************************************************/
|
||||
#if defined(STM32F100xB) ||defined(STM32F100xE)
|
||||
uint32_t SystemCoreClock = 24000000; /*!< System Clock Frequency (Core Clock) */
|
||||
#else /*!< HSI Selected as System Clock source */
|
||||
uint32_t SystemCoreClock = 72000000; /*!< System Clock Frequency (Core Clock) */
|
||||
#endif
|
||||
|
||||
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemCoreClock variable.
|
||||
* @note This function should be used only after reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
/* Reset the RCC clock configuration to the default reset state(for debug purpose) */
|
||||
/* Set HSION bit */
|
||||
RCC->CR |= (uint32_t)0x00000001;
|
||||
|
||||
/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
RCC->CFGR &= (uint32_t)0xF8FF0000;
|
||||
#else
|
||||
RCC->CFGR &= (uint32_t)0xF0FF0000;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
/* Reset HSEON, CSSON and PLLON bits */
|
||||
RCC->CR &= (uint32_t)0xFEF6FFFF;
|
||||
|
||||
/* Reset HSEBYP bit */
|
||||
RCC->CR &= (uint32_t)0xFFFBFFFF;
|
||||
|
||||
/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
|
||||
RCC->CFGR &= (uint32_t)0xFF80FFFF;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/* Reset PLL2ON and PLL3ON bits */
|
||||
RCC->CR &= (uint32_t)0xEBFFFFFF;
|
||||
|
||||
/* Disable all interrupts and clear pending bits */
|
||||
RCC->CIR = 0x00FF0000;
|
||||
|
||||
/* Reset CFGR2 register */
|
||||
RCC->CFGR2 = 0x00000000;
|
||||
#elif defined(STM32F100xB) || defined(STM32F100xE)
|
||||
/* Disable all interrupts and clear pending bits */
|
||||
RCC->CIR = 0x009F0000;
|
||||
|
||||
/* Reset CFGR2 register */
|
||||
RCC->CFGR2 = 0x00000000;
|
||||
#else
|
||||
/* Disable all interrupts and clear pending bits */
|
||||
RCC->CIR = 0x009F0000;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif
|
||||
|
||||
#ifdef VECT_TAB_SRAM
|
||||
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
|
||||
#else
|
||||
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Update SystemCoreClock variable according to Clock Register Values.
|
||||
* The SystemCoreClock variable contains the core clock (HCLK), it can
|
||||
* be used by the user application to setup the SysTick timer or configure
|
||||
* other parameters.
|
||||
*
|
||||
* @note Each time the core clock (HCLK) changes, this function must be called
|
||||
* to update SystemCoreClock variable value. Otherwise, any configuration
|
||||
* based on this variable will be incorrect.
|
||||
*
|
||||
* @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:
|
||||
*
|
||||
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
|
||||
*
|
||||
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
*
|
||||
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
|
||||
* or HSI_VALUE(*) multiplied by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
|
||||
* that HSE_VALUE is same as the real frequency of the crystal used.
|
||||
* Otherwise, this function may have wrong result.
|
||||
*
|
||||
* - The result of this function could be not correct when using fractional
|
||||
* value for HSE crystal.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemCoreClockUpdate (void)
|
||||
{
|
||||
uint32_t tmp = 0, pllmull = 0, pllsource = 0;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1source = 0, prediv1factor = 0, prediv2factor = 0, pll2mull = 0;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
uint32_t prediv1factor = 0;
|
||||
#endif /* STM32F100xB or STM32F100xE */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08: /* PLL used as system clock */
|
||||
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
pllmull = ( pllmull >> 18) + 2;
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
#else
|
||||
/* HSE selected as PLL clock entry */
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||
{/* HSE oscillator clock divided by 2 */
|
||||
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pllmull = pllmull >> 18;
|
||||
|
||||
if (pllmull != 0x0D)
|
||||
{
|
||||
pllmull += 2;
|
||||
}
|
||||
else
|
||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||
pllmull = 13 / 2;
|
||||
}
|
||||
|
||||
if (pllsource == 0x00)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PREDIV1 selected as PLL clock entry */
|
||||
|
||||
/* Get PREDIV1 clock source and division factor */
|
||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1;
|
||||
|
||||
if (prediv1source == 0)
|
||||
{
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||
|
||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4) + 1;
|
||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8 ) + 2;
|
||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC */
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/**
|
||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||
* before jump to __main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||
* board (STM32 High density devices). This SRAM will be used as program
|
||||
* data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||
required, then adjust the Register Addresses */
|
||||
|
||||
/* Enable FSMC clock */
|
||||
RCC->AHBENR = 0x00000114;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||
RCC->APB2ENR = 0x000001E0;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||
|
||||
(void)(tmpreg);
|
||||
|
||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||
/*---------------- NE3 configuration ----------------------------------------*/
|
||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||
|
||||
GPIOD->CRL = 0x44BB44BB;
|
||||
GPIOD->CRH = 0xBBBBBBBB;
|
||||
|
||||
GPIOE->CRL = 0xB44444BB;
|
||||
GPIOE->CRH = 0xBBBBBBBB;
|
||||
|
||||
GPIOF->CRL = 0x44BBBBBB;
|
||||
GPIOF->CRH = 0xBBBB4444;
|
||||
|
||||
GPIOG->CRL = 0x44BBBBBB;
|
||||
GPIOG->CRH = 0x444B4B44;
|
||||
|
||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||
|
||||
FSMC_Bank1->BTCR[4] = 0x00001091;
|
||||
FSMC_Bank1->BTCR[5] = 0x00110212;
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
87
system/src/cortexm/_initialize_hardware.c
Normal file
87
system/src/cortexm/_initialize_hardware.c
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "cmsis_device.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern unsigned int __vectors_start;
|
||||
|
||||
// Forward declarations.
|
||||
|
||||
void
|
||||
__initialize_hardware_early(void);
|
||||
|
||||
void
|
||||
__initialize_hardware(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is the early hardware initialisation routine, it can be
|
||||
// redefined in the application for more complex cases that
|
||||
// require early inits (before BSS init).
|
||||
//
|
||||
// Called early from _start(), right before data & bss init.
|
||||
//
|
||||
// After Reset the Cortex-M processor is in Thread mode,
|
||||
// priority is Privileged, and the Stack is set to Main.
|
||||
|
||||
void
|
||||
__attribute__((weak))
|
||||
__initialize_hardware_early(void)
|
||||
{
|
||||
// Call the CSMSIS system initialisation routine.
|
||||
SystemInit();
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
// Set VTOR to the actual address, provided by the linker script.
|
||||
// Override the manual, possibly wrong, SystemInit() setting.
|
||||
SCB->VTOR = (uint32_t)(&__vectors_start);
|
||||
#endif
|
||||
|
||||
// The current version of SystemInit() leaves the value of the clock
|
||||
// in a RAM variable (SystemCoreClock), which will be cleared shortly,
|
||||
// so it needs to be recomputed after the RAM initialisations
|
||||
// are completed.
|
||||
|
||||
#if defined(OS_INCLUDE_STARTUP_INIT_FP) || (defined (__VFP_FP__) && !defined (__SOFTFP__))
|
||||
|
||||
// Normally FP init is done by SystemInit(). In case this is not done
|
||||
// there, it is possible to force its inclusion by defining
|
||||
// OS_INCLUDE_STARTUP_INIT_FP.
|
||||
|
||||
// Enable the Cortex-M4 FPU only when -mfloat-abi=hard.
|
||||
// Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C)
|
||||
|
||||
// Set bits 20-23 to enable CP10 and CP11 coprocessor
|
||||
SCB->CPACR |= (0xF << 20);
|
||||
|
||||
#endif // (__VFP_FP__) && !(__SOFTFP__)
|
||||
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This is the second hardware initialisation routine, it can be
|
||||
// redefined in the application for more complex cases that
|
||||
// require custom inits (before constructors), otherwise these can
|
||||
// be done in main().
|
||||
//
|
||||
// Called from _start(), right after data & bss init, before
|
||||
// constructors.
|
||||
|
||||
void
|
||||
__attribute__((weak))
|
||||
__initialize_hardware(void)
|
||||
{
|
||||
// Call the CSMSIS system clock routine to store the clock frequency
|
||||
// in the SystemCoreClock global RAM location.
|
||||
SystemCoreClockUpdate();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
37
system/src/cortexm/_reset_hardware.c
Normal file
37
system/src/cortexm/_reset_hardware.c
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "cmsis_device.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern void
|
||||
__attribute__((noreturn))
|
||||
NVIC_SystemReset(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Forward declarations
|
||||
|
||||
void
|
||||
__reset_hardware(void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is the default hardware reset routine; it can be
|
||||
// redefined in the application for more complex applications.
|
||||
//
|
||||
// Called from _exit().
|
||||
|
||||
void
|
||||
__attribute__((weak,noreturn))
|
||||
__reset_hardware()
|
||||
{
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
599
system/src/cortexm/exception_handlers.c
Normal file
599
system/src/cortexm/exception_handlers.c
Normal file
@ -0,0 +1,599 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "cortexm/ExceptionHandlers.h"
|
||||
#include "cmsis_device.h"
|
||||
#include "arm/semihosting.h"
|
||||
#include "diag/Trace.h"
|
||||
#include <string.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern void
|
||||
__attribute__((noreturn,weak))
|
||||
_start (void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Default exception handlers. Override the ones here by defining your own
|
||||
// handler routines in your application code.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
// The DEBUG version is not naked, but has a proper stack frame,
|
||||
// to allow setting breakpoints at Reset_Handler.
|
||||
void __attribute__ ((section(".after_vectors"),noreturn))
|
||||
Reset_Handler (void)
|
||||
{
|
||||
_start ();
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// The Release version is optimised to a quick branch to _start.
|
||||
void __attribute__ ((section(".after_vectors"),naked))
|
||||
Reset_Handler(void)
|
||||
{
|
||||
asm volatile
|
||||
(
|
||||
" ldr r0,=_start \n"
|
||||
" bx r0"
|
||||
:
|
||||
:
|
||||
:
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
NMI_Handler (void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(TRACE)
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
// The values of BFAR and MMFAR stay unchanged if the BFARVALID or
|
||||
// MMARVALID is set. However, if a new fault occurs during the
|
||||
// execution of this fault handler, the value of the BFAR and MMFAR
|
||||
// could potentially be erased. In order to ensure the fault addresses
|
||||
// accessed are valid, the following procedure should be used:
|
||||
// 1. Read BFAR/MMFAR.
|
||||
// 2. Read CFSR to get BFARVALID or MMARVALID. If the value is 0, the
|
||||
// value of BFAR or MMFAR accessed can be invalid and can be discarded.
|
||||
// 3. Optionally clear BFARVALID or MMARVALID.
|
||||
// (See Joseph Yiu's book).
|
||||
|
||||
void
|
||||
dumpExceptionStack (ExceptionStackFrame* frame,
|
||||
uint32_t cfsr, uint32_t mmfar, uint32_t bfar,
|
||||
uint32_t lr)
|
||||
{
|
||||
trace_printf ("Stack frame:\n");
|
||||
trace_printf (" R0 = %08X\n", frame->r0);
|
||||
trace_printf (" R1 = %08X\n", frame->r1);
|
||||
trace_printf (" R2 = %08X\n", frame->r2);
|
||||
trace_printf (" R3 = %08X\n", frame->r3);
|
||||
trace_printf (" R12 = %08X\n", frame->r12);
|
||||
trace_printf (" LR = %08X\n", frame->lr);
|
||||
trace_printf (" PC = %08X\n", frame->pc);
|
||||
trace_printf (" PSR = %08X\n", frame->psr);
|
||||
trace_printf ("FSR/FAR:\n");
|
||||
trace_printf (" CFSR = %08X\n", cfsr);
|
||||
trace_printf (" HFSR = %08X\n", SCB->HFSR);
|
||||
trace_printf (" DFSR = %08X\n", SCB->DFSR);
|
||||
trace_printf (" AFSR = %08X\n", SCB->AFSR);
|
||||
|
||||
if (cfsr & (1UL << 7))
|
||||
{
|
||||
trace_printf (" MMFAR = %08X\n", mmfar);
|
||||
}
|
||||
if (cfsr & (1UL << 15))
|
||||
{
|
||||
trace_printf (" BFAR = %08X\n", bfar);
|
||||
}
|
||||
trace_printf ("Misc\n");
|
||||
trace_printf (" LR/EXC_RETURN= %08X\n", lr);
|
||||
}
|
||||
|
||||
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
#if defined(__ARM_ARCH_6M__)
|
||||
|
||||
void
|
||||
dumpExceptionStack (ExceptionStackFrame* frame, uint32_t lr)
|
||||
{
|
||||
trace_printf ("Stack frame:\n");
|
||||
trace_printf (" R0 = %08X\n", frame->r0);
|
||||
trace_printf (" R1 = %08X\n", frame->r1);
|
||||
trace_printf (" R2 = %08X\n", frame->r2);
|
||||
trace_printf (" R3 = %08X\n", frame->r3);
|
||||
trace_printf (" R12 = %08X\n", frame->r12);
|
||||
trace_printf (" LR = %08X\n", frame->lr);
|
||||
trace_printf (" PC = %08X\n", frame->pc);
|
||||
trace_printf (" PSR = %08X\n", frame->psr);
|
||||
trace_printf ("Misc\n");
|
||||
trace_printf (" LR/EXC_RETURN= %08X\n", lr);
|
||||
}
|
||||
|
||||
#endif // defined(__ARM_ARCH_6M__)
|
||||
|
||||
#endif // defined(TRACE)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
|
||||
int
|
||||
isSemihosting (ExceptionStackFrame* frame, uint16_t opCode);
|
||||
|
||||
/**
|
||||
* This function provides the minimum functionality to make a semihosting program execute even without the debugger present.
|
||||
* @param frame pointer to an exception stack frame.
|
||||
* @param opCode the 16-bin word of the BKPT instruction.
|
||||
* @return 1 if the instruction was a valid semihosting call; 0 otherwise.
|
||||
*/
|
||||
int
|
||||
isSemihosting (ExceptionStackFrame* frame, uint16_t opCode)
|
||||
{
|
||||
uint16_t* pw = (uint16_t*) frame->pc;
|
||||
if (*pw == opCode)
|
||||
{
|
||||
uint32_t r0 = frame->r0;
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS) || defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
uint32_t r1 = frame->r1;
|
||||
#endif
|
||||
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
uint32_t* blk = (uint32_t*) r1;
|
||||
#endif
|
||||
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
// trace_printf ("sh r0=%d\n", r0);
|
||||
#endif
|
||||
|
||||
switch (r0)
|
||||
{
|
||||
|
||||
#if defined(OS_USE_SEMIHOSTING)
|
||||
|
||||
case SEMIHOSTING_SYS_CLOCK:
|
||||
case SEMIHOSTING_SYS_ELAPSED:
|
||||
case SEMIHOSTING_SYS_FLEN:
|
||||
case SEMIHOSTING_SYS_GET_CMDLINE:
|
||||
case SEMIHOSTING_SYS_REMOVE:
|
||||
case SEMIHOSTING_SYS_RENAME:
|
||||
case SEMIHOSTING_SYS_SEEK:
|
||||
case SEMIHOSTING_SYS_SYSTEM:
|
||||
case SEMIHOSTING_SYS_TICKFREQ:
|
||||
case SEMIHOSTING_SYS_TMPNAM:
|
||||
case SEMIHOSTING_SYS_ISTTY:
|
||||
frame->r0 = (uint32_t)-1; // the call is not successful or not supported
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_CLOSE:
|
||||
frame->r0 = 0; // call is successful
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_ERRNO:
|
||||
frame->r0 = 0; // the value of the C library errno variable.
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_HEAPINFO:
|
||||
blk[0] = 0; // heap_base
|
||||
blk[1] = 0; // heap_limit
|
||||
blk[2] = 0; // stack_base
|
||||
blk[3] = 0; // stack_limit
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_ISERROR:
|
||||
frame->r0 = 0; // 0 if the status word is not an error indication
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_READ:
|
||||
// If R0 contains the same value as word 3, the call has
|
||||
// failed and EOF is assumed.
|
||||
frame->r0 = blk[2];
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_READC:
|
||||
frame->r0 = '\0'; // the byte read from the console.
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_TIME:
|
||||
frame->r0 = 0; // the number of seconds since 00:00 January 1, 1970.
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_ReportException:
|
||||
|
||||
NVIC_SystemReset ();
|
||||
// Should not reach here
|
||||
return 0;
|
||||
|
||||
#endif // defined(OS_USE_SEMIHOSTING)
|
||||
|
||||
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
|
||||
#define HANDLER_STDIN (1)
|
||||
#define HANDLER_STDOUT (2)
|
||||
#define HANDLER_STDERR (3)
|
||||
|
||||
case SEMIHOSTING_SYS_OPEN:
|
||||
// Process only standard io/out/err and return 1/2/3
|
||||
if (strcmp ((char*) blk[0], ":tt") == 0)
|
||||
{
|
||||
if ((blk[1] == 0))
|
||||
{
|
||||
frame->r0 = HANDLER_STDIN;
|
||||
break;
|
||||
}
|
||||
else if (blk[1] == 4)
|
||||
{
|
||||
frame->r0 = HANDLER_STDOUT;
|
||||
break;
|
||||
}
|
||||
else if (blk[1] == 8)
|
||||
{
|
||||
frame->r0 = HANDLER_STDERR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
frame->r0 = (uint32_t)-1; // the call is not successful or not supported
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_WRITE:
|
||||
// Silently ignore writes to stdout/stderr, fail on all other handler.
|
||||
if ((blk[0] == HANDLER_STDOUT) || (blk[0] == HANDLER_STDERR))
|
||||
{
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
frame->r0 = (uint32_t) blk[2]
|
||||
- trace_write ((char*) blk[1], blk[2]);
|
||||
#else
|
||||
frame->r0 = 0; // all sent, no more.
|
||||
#endif // defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
}
|
||||
else
|
||||
{
|
||||
// If other handler, return the total number of bytes
|
||||
// as the number of bytes that are not written.
|
||||
frame->r0 = blk[2];
|
||||
}
|
||||
break;
|
||||
|
||||
#endif // defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
|
||||
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
|
||||
case SEMIHOSTING_SYS_WRITEC:
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
{
|
||||
char ch = *((char*) r1);
|
||||
trace_write (&ch, 1);
|
||||
}
|
||||
#endif
|
||||
// Register R0 is corrupted.
|
||||
break;
|
||||
|
||||
case SEMIHOSTING_SYS_WRITE0:
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
{
|
||||
char* p = ((char*) r1);
|
||||
trace_write (p, strlen (p));
|
||||
}
|
||||
#endif
|
||||
// Register R0 is corrupted.
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Alter the PC to make the exception returns to
|
||||
// the instruction after the faulty BKPT.
|
||||
frame->pc += 2;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Hard Fault handler wrapper in assembly.
|
||||
// It extracts the location of stack frame and passes it to handler
|
||||
// in C as a pointer. We also pass the LR value as second
|
||||
// parameter.
|
||||
// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M3 and
|
||||
// Cortex-M4 Processors, Third Edition, Chap. 12.8, page 402).
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,naked))
|
||||
HardFault_Handler (void)
|
||||
{
|
||||
asm volatile(
|
||||
" tst lr,#4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0,msp \n"
|
||||
" mrsne r0,psp \n"
|
||||
" mov r1,lr \n"
|
||||
" ldr r2,=HardFault_Handler_C \n"
|
||||
" bx r2"
|
||||
|
||||
: /* Outputs */
|
||||
: /* Inputs */
|
||||
: /* Clobbers */
|
||||
);
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,used))
|
||||
HardFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
|
||||
uint32_t lr __attribute__((unused)))
|
||||
{
|
||||
#if defined(TRACE)
|
||||
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
|
||||
uint32_t bfar = SCB->BFAR; // Bus Fault Address
|
||||
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
|
||||
#endif
|
||||
|
||||
#if defined(OS_USE_SEMIHOSTING) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
|
||||
// If the BKPT instruction is executed with C_DEBUGEN == 0 and MON_EN == 0,
|
||||
// it will cause the processor to enter a HardFault exception, with DEBUGEVT
|
||||
// in the Hard Fault Status register (HFSR) set to 1, and BKPT in the
|
||||
// Debug Fault Status register (DFSR) also set to 1.
|
||||
|
||||
if (((SCB->DFSR & SCB_DFSR_BKPT_Msk) != 0)
|
||||
&& ((SCB->HFSR & SCB_HFSR_DEBUGEVT_Msk) != 0))
|
||||
{
|
||||
if (isSemihosting (frame, 0xBE00 + (AngelSWI & 0xFF)))
|
||||
{
|
||||
// Clear the exception cause in exception status.
|
||||
SCB->HFSR = SCB_HFSR_DEBUGEVT_Msk;
|
||||
|
||||
// Continue after the BKPT
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TRACE)
|
||||
trace_printf ("[HardFault]\n");
|
||||
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
|
||||
#endif // defined(TRACE)
|
||||
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_6M__)
|
||||
|
||||
// Hard Fault handler wrapper in assembly.
|
||||
// It extracts the location of stack frame and passes it to handler
|
||||
// in C as a pointer. We also pass the LR value as second
|
||||
// parameter.
|
||||
// (Based on Joseph Yiu's, The Definitive Guide to ARM Cortex-M0
|
||||
// First Edition, Chap. 12.8, page 402).
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,naked))
|
||||
HardFault_Handler (void)
|
||||
{
|
||||
asm volatile(
|
||||
" movs r0,#4 \n"
|
||||
" mov r1,lr \n"
|
||||
" tst r0,r1 \n"
|
||||
" beq 1f \n"
|
||||
" mrs r0,psp \n"
|
||||
" b 2f \n"
|
||||
"1: \n"
|
||||
" mrs r0,msp \n"
|
||||
"2:"
|
||||
" mov r1,lr \n"
|
||||
" ldr r2,=HardFault_Handler_C \n"
|
||||
" bx r2"
|
||||
|
||||
: /* Outputs */
|
||||
: /* Inputs */
|
||||
: /* Clobbers */
|
||||
);
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,used))
|
||||
HardFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
|
||||
uint32_t lr __attribute__((unused)))
|
||||
{
|
||||
// There is no semihosting support for Cortex-M0, since on ARMv6-M
|
||||
// faults are fatal and it is not possible to return from the handler.
|
||||
|
||||
#if defined(TRACE)
|
||||
trace_printf ("[HardFault]\n");
|
||||
dumpExceptionStack (frame, lr);
|
||||
#endif // defined(TRACE)
|
||||
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__ARM_ARCH_6M__)
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
MemManage_Handler (void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,naked))
|
||||
BusFault_Handler (void)
|
||||
{
|
||||
asm volatile(
|
||||
" tst lr,#4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0,msp \n"
|
||||
" mrsne r0,psp \n"
|
||||
" mov r1,lr \n"
|
||||
" ldr r2,=BusFault_Handler_C \n"
|
||||
" bx r2"
|
||||
|
||||
: /* Outputs */
|
||||
: /* Inputs */
|
||||
: /* Clobbers */
|
||||
);
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,used))
|
||||
BusFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
|
||||
uint32_t lr __attribute__((unused)))
|
||||
{
|
||||
#if defined(TRACE)
|
||||
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
|
||||
uint32_t bfar = SCB->BFAR; // Bus Fault Address
|
||||
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
|
||||
|
||||
trace_printf ("[BusFault]\n");
|
||||
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
|
||||
#endif // defined(TRACE)
|
||||
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,naked))
|
||||
UsageFault_Handler (void)
|
||||
{
|
||||
asm volatile(
|
||||
" tst lr,#4 \n"
|
||||
" ite eq \n"
|
||||
" mrseq r0,msp \n"
|
||||
" mrsne r0,psp \n"
|
||||
" mov r1,lr \n"
|
||||
" ldr r2,=UsageFault_Handler_C \n"
|
||||
" bx r2"
|
||||
|
||||
: /* Outputs */
|
||||
: /* Inputs */
|
||||
: /* Clobbers */
|
||||
);
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak,used))
|
||||
UsageFault_Handler_C (ExceptionStackFrame* frame __attribute__((unused)),
|
||||
uint32_t lr __attribute__((unused)))
|
||||
{
|
||||
#if defined(TRACE)
|
||||
uint32_t mmfar = SCB->MMFAR; // MemManage Fault Address
|
||||
uint32_t bfar = SCB->BFAR; // Bus Fault Address
|
||||
uint32_t cfsr = SCB->CFSR; // Configurable Fault Status Registers
|
||||
#endif
|
||||
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
|
||||
if ((cfsr & (1UL << 16)) != 0) // UNDEFINSTR
|
||||
{
|
||||
// For testing purposes, instead of BKPT use 'setend be'.
|
||||
if (isSemihosting (frame, AngelSWITestFaultOpCode))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TRACE)
|
||||
trace_printf ("[UsageFault]\n");
|
||||
dumpExceptionStack (frame, cfsr, mmfar, bfar, lr);
|
||||
#endif // defined(TRACE)
|
||||
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
SVC_Handler (void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
DebugMon_Handler (void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
PendSV_Handler (void)
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
__DEBUG_BKPT();
|
||||
#endif
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),weak))
|
||||
SysTick_Handler (void)
|
||||
{
|
||||
// DO NOT loop, just return.
|
||||
// Useful in case someone (like STM HAL) inadvertently enables SysTick.
|
||||
;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
76
system/src/diag/Trace.c
Normal file
76
system/src/diag/Trace.c
Normal file
@ -0,0 +1,76 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(TRACE)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "diag/Trace.h"
|
||||
#include "string.h"
|
||||
|
||||
#ifndef OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE
|
||||
#define OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE (128)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int
|
||||
trace_printf(const char* format, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, format);
|
||||
|
||||
// TODO: rewrite it to no longer use newlib, it is way too heavy
|
||||
|
||||
static char buf[OS_INTEGER_TRACE_PRINTF_TMP_ARRAY_SIZE];
|
||||
|
||||
// Print to the local buffer
|
||||
ret = vsnprintf (buf, sizeof(buf), format, ap);
|
||||
if (ret > 0)
|
||||
{
|
||||
// Transfer the buffer to the device
|
||||
ret = trace_write (buf, (size_t)ret);
|
||||
}
|
||||
|
||||
va_end (ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
trace_puts(const char *s)
|
||||
{
|
||||
trace_write(s, strlen(s));
|
||||
return trace_write("\n", 1);
|
||||
}
|
||||
|
||||
int
|
||||
trace_putchar(int c)
|
||||
{
|
||||
trace_write((const char*)&c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
trace_dump_args(int argc, char* argv[])
|
||||
{
|
||||
trace_printf("main(argc=%d, argv=[", argc);
|
||||
for (int i = 0; i < argc; ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
{
|
||||
trace_printf(", ");
|
||||
}
|
||||
trace_printf("\"%s\"", argv[i]);
|
||||
}
|
||||
trace_printf("]);\n");
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#endif // TRACE
|
252
system/src/diag/trace_impl.c
Normal file
252
system/src/diag/trace_impl.c
Normal file
@ -0,0 +1,252 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(TRACE)
|
||||
|
||||
#include "cmsis_device.h"
|
||||
#include "diag/Trace.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// One of these definitions must be passed via the compiler command line
|
||||
// Note: small Cortex-M0/M0+ might implement a simplified debug interface.
|
||||
|
||||
//#define OS_USE_TRACE_ITM
|
||||
//#define OS_USE_TRACE_SEMIHOSTING_DEBUG
|
||||
//#define OS_USE_TRACE_SEMIHOSTING_STDOUT
|
||||
|
||||
#if !(defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
#if defined(OS_USE_TRACE_ITM)
|
||||
#undef OS_USE_TRACE_ITM
|
||||
#warning "ITM unavailable"
|
||||
#endif // defined(OS_USE_TRACE_ITM)
|
||||
#endif // !(defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
|
||||
|
||||
#if defined(OS_DEBUG_SEMIHOSTING_FAULTS)
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT) || defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
#error "Cannot debug semihosting using semihosting trace; use OS_USE_TRACE_ITM"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Forward definitions.
|
||||
|
||||
#if defined(OS_USE_TRACE_ITM)
|
||||
static ssize_t
|
||||
_trace_write_itm (const char* buf, size_t nbyte);
|
||||
#endif
|
||||
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
static ssize_t
|
||||
_trace_write_semihosting_stdout(const char* buf, size_t nbyte);
|
||||
#endif
|
||||
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
static ssize_t
|
||||
_trace_write_semihosting_debug(const char* buf, size_t nbyte);
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
trace_initialize(void)
|
||||
{
|
||||
// For regular ITM / semihosting, no inits required.
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This function is called from _write() for fd==1 or fd==2 and from some
|
||||
// of the trace_* functions.
|
||||
|
||||
ssize_t
|
||||
trace_write (const char* buf __attribute__((unused)),
|
||||
size_t nbyte __attribute__((unused)))
|
||||
{
|
||||
#if defined(OS_USE_TRACE_ITM)
|
||||
return _trace_write_itm (buf, nbyte);
|
||||
#elif defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
return _trace_write_semihosting_stdout(buf, nbyte);
|
||||
#elif defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
return _trace_write_semihosting_debug(buf, nbyte);
|
||||
#endif
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(OS_USE_TRACE_ITM)
|
||||
|
||||
#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
// ITM is the ARM standard mechanism, running over SWD/SWO on Cortex-M3/M4
|
||||
// devices, and is the recommended setting, if available.
|
||||
//
|
||||
// The JLink probe and the GDB server fully support SWD/SWO
|
||||
// and the JLink Debugging plug-in enables it by default.
|
||||
// The current OpenOCD does not include support to parse the SWO stream,
|
||||
// so this configuration will not work on OpenOCD (will not crash, but
|
||||
// nothing will be displayed in the output console).
|
||||
|
||||
#if !defined(OS_INTEGER_TRACE_ITM_STIMULUS_PORT)
|
||||
#define OS_INTEGER_TRACE_ITM_STIMULUS_PORT (0)
|
||||
#endif
|
||||
|
||||
static ssize_t
|
||||
_trace_write_itm (const char* buf, size_t nbyte)
|
||||
{
|
||||
for (size_t i = 0; i < nbyte; i++)
|
||||
{
|
||||
// Check if ITM or the stimulus port are not enabled
|
||||
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) == 0)
|
||||
|| ((ITM->TER & (1UL << OS_INTEGER_TRACE_ITM_STIMULUS_PORT)) == 0))
|
||||
{
|
||||
return (ssize_t)i; // return the number of sent characters (may be 0)
|
||||
}
|
||||
|
||||
// Wait until STIMx is ready...
|
||||
while (ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u32 == 0)
|
||||
;
|
||||
// then send data, one byte at a time
|
||||
ITM->PORT[OS_INTEGER_TRACE_ITM_STIMULUS_PORT].u8 = (uint8_t) (*buf++);
|
||||
}
|
||||
|
||||
return (ssize_t)nbyte; // all characters successfully sent
|
||||
}
|
||||
|
||||
#endif // defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
|
||||
|
||||
#endif // OS_USE_TRACE_ITM
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG) || defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
|
||||
#include "arm/semihosting.h"
|
||||
|
||||
// Semihosting is the other output channel that can be used for the trace
|
||||
// messages. It comes in two flavours: STDOUT and DEBUG. The STDOUT channel
|
||||
// is the equivalent of the stdout in POSIX and in most cases it is forwarded
|
||||
// to the GDB server stdout stream. The debug channel is a separate
|
||||
// channel. STDOUT is buffered, so nothing is displayed until a \n;
|
||||
// DEBUG is not buffered, but can be slow.
|
||||
//
|
||||
// Choosing between semihosting stdout and debug depends on the capabilities
|
||||
// of your GDB server, and also on specific needs. It is recommended to test
|
||||
// DEBUG first, and if too slow, try STDOUT.
|
||||
//
|
||||
// The JLink GDB server fully support semihosting, and both configurations
|
||||
// are available; to activate it, use "monitor semihosting enable" or check
|
||||
// the corresponding button in the JLink Debugging plug-in.
|
||||
// In OpenOCD, support for semihosting can be enabled using
|
||||
// "monitor arm semihosting enable".
|
||||
//
|
||||
// Note: Applications built with semihosting output active normally cannot
|
||||
// be executed without the debugger connected and active, since they use
|
||||
// BKPT to communicate with the host. However, with a carefully written
|
||||
// HardFault_Handler, the semihosting BKPT calls can be processed, making
|
||||
// possible to run semihosting applications as standalone, without being
|
||||
// terminated with hardware faults.
|
||||
|
||||
#endif // OS_USE_TRACE_SEMIHOSTING_DEBUG_*
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_STDOUT)
|
||||
|
||||
static ssize_t
|
||||
_trace_write_semihosting_stdout (const char* buf, size_t nbyte)
|
||||
{
|
||||
static int handle;
|
||||
void* block[3];
|
||||
int ret;
|
||||
|
||||
if (handle == 0)
|
||||
{
|
||||
// On the first call get the file handle from the host
|
||||
block[0] = ":tt"; // special filename to be used for stdin/out/err
|
||||
block[1] = (void*) 4; // mode "w"
|
||||
// length of ":tt", except null terminator
|
||||
block[2] = (void*) (sizeof(":tt") - 1);
|
||||
|
||||
ret = call_host (SEMIHOSTING_SYS_OPEN, (void*) block);
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
handle = ret;
|
||||
}
|
||||
|
||||
block[0] = (void*) handle;
|
||||
block[1] = (void*) buf;
|
||||
block[2] = (void*) nbyte;
|
||||
// send character array to host file/device
|
||||
ret = call_host (SEMIHOSTING_SYS_WRITE, (void*) block);
|
||||
// this call returns the number of bytes NOT written (0 if all ok)
|
||||
|
||||
// -1 is not a legal value, but SEGGER seems to return it
|
||||
if (ret == -1)
|
||||
return -1;
|
||||
|
||||
// The compliant way of returning errors
|
||||
if (ret == (int) nbyte)
|
||||
return -1;
|
||||
|
||||
// Return the number of bytes written
|
||||
return (ssize_t) (nbyte) - (ssize_t) ret;
|
||||
}
|
||||
|
||||
#endif // OS_USE_TRACE_SEMIHOSTING_STDOUT
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if defined(OS_USE_TRACE_SEMIHOSTING_DEBUG)
|
||||
|
||||
#define OS_INTEGER_TRACE_TMP_ARRAY_SIZE (16)
|
||||
|
||||
static ssize_t
|
||||
_trace_write_semihosting_debug (const char* buf, size_t nbyte)
|
||||
{
|
||||
// Since the single character debug channel is quite slow, try to
|
||||
// optimise and send a null terminated string, if possible.
|
||||
if (buf[nbyte] == '\0')
|
||||
{
|
||||
// send string
|
||||
call_host (SEMIHOSTING_SYS_WRITE0, (void*) buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If not, use a local buffer to speed things up
|
||||
char tmp[OS_INTEGER_TRACE_TMP_ARRAY_SIZE];
|
||||
size_t togo = nbyte;
|
||||
while (togo > 0)
|
||||
{
|
||||
unsigned int n = ((togo < sizeof(tmp)) ? togo : sizeof(tmp));
|
||||
unsigned int i = 0;
|
||||
for (; i < n; ++i, ++buf)
|
||||
{
|
||||
tmp[i] = *buf;
|
||||
}
|
||||
tmp[i] = '\0';
|
||||
|
||||
call_host (SEMIHOSTING_SYS_WRITE0, (void*) tmp);
|
||||
|
||||
togo -= n;
|
||||
}
|
||||
}
|
||||
|
||||
// All bytes written
|
||||
return (ssize_t) nbyte;
|
||||
}
|
||||
|
||||
#endif // OS_USE_TRACE_SEMIHOSTING_DEBUG
|
||||
|
||||
#endif // TRACE
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
16
system/src/newlib/README.txt
Normal file
16
system/src/newlib/README.txt
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
The following files extend or replace some of the the newlib functionality:
|
||||
|
||||
_startup.c: a customised startup sequence, written in C
|
||||
|
||||
_exit.c: a customised exit() implementation
|
||||
|
||||
_syscalls.c: local versions of the libnosys/librdimon code
|
||||
|
||||
_sbrk.c: a custom _sbrk() to match the actual linker scripts
|
||||
|
||||
assert.c: implementation for the asserion macros
|
||||
|
||||
_cxx.cpp: local versions of some C++ support, to avoid references to
|
||||
large functions.
|
||||
|
50
system/src/newlib/_cxx.cpp
Normal file
50
system/src/newlib/_cxx.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// These functions are redefined locally, to avoid references to some
|
||||
// heavy implementations in the standard C++ library.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sys/types.h>
|
||||
#include "diag/Trace.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
namespace __gnu_cxx
|
||||
{
|
||||
void
|
||||
__attribute__((noreturn))
|
||||
__verbose_terminate_handler();
|
||||
|
||||
void
|
||||
__verbose_terminate_handler()
|
||||
{
|
||||
trace_puts(__func__);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void
|
||||
__attribute__((noreturn))
|
||||
__cxa_pure_virtual();
|
||||
|
||||
void
|
||||
__cxa_pure_virtual()
|
||||
{
|
||||
trace_puts(__func__);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
59
system/src/newlib/_exit.c
Normal file
59
system/src/newlib/_exit.c
Normal file
@ -0,0 +1,59 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "diag/Trace.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(DEBUG)
|
||||
extern void
|
||||
__attribute__((noreturn))
|
||||
__reset_hardware(void);
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Forward declaration
|
||||
|
||||
void
|
||||
_exit(int code);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// On Release, call the hardware reset procedure.
|
||||
// On Debug we just enter an infinite loop, to be used as landmark when halting
|
||||
// the debugger.
|
||||
//
|
||||
// It can be redefined in the application, if more functionality
|
||||
// is required.
|
||||
|
||||
void
|
||||
__attribute__((weak))
|
||||
_exit(int code __attribute__((unused)))
|
||||
{
|
||||
#if !defined(DEBUG)
|
||||
__reset_hardware();
|
||||
#endif
|
||||
|
||||
// TODO: write on trace
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
__attribute__((weak,noreturn))
|
||||
abort(void)
|
||||
{
|
||||
trace_puts("abort(), exiting...");
|
||||
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
65
system/src/newlib/_sbrk.c
Normal file
65
system/src/newlib/_sbrk.c
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
caddr_t
|
||||
_sbrk(int incr);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// The definitions used here should be kept in sync with the
|
||||
// stack definitions in the linker script.
|
||||
|
||||
caddr_t
|
||||
_sbrk(int incr)
|
||||
{
|
||||
extern char _Heap_Begin; // Defined by the linker.
|
||||
extern char _Heap_Limit; // Defined by the linker.
|
||||
|
||||
static char* current_heap_end;
|
||||
char* current_block_address;
|
||||
|
||||
if (current_heap_end == 0)
|
||||
{
|
||||
current_heap_end = &_Heap_Begin;
|
||||
}
|
||||
|
||||
current_block_address = current_heap_end;
|
||||
|
||||
// Need to align heap to word boundary, else will get
|
||||
// hard faults on Cortex-M0. So we assume that heap starts on
|
||||
// word boundary, hence make sure we always add a multiple of
|
||||
// 4 to it.
|
||||
incr = (incr + 3) & (~3); // align value to 4
|
||||
if (current_heap_end + incr > &_Heap_Limit)
|
||||
{
|
||||
// Some of the libstdc++-v3 tests rely upon detecting
|
||||
// out of memory errors, so do not abort here.
|
||||
#if 0
|
||||
extern void abort (void);
|
||||
|
||||
_write (1, "_sbrk: Heap and stack collision\n", 32);
|
||||
|
||||
abort ();
|
||||
#else
|
||||
// Heap has overflowed
|
||||
errno = ENOMEM;
|
||||
return (caddr_t) - 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
current_heap_end += incr;
|
||||
|
||||
return (caddr_t) current_block_address;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
327
system/src/newlib/_startup.c
Normal file
327
system/src/newlib/_startup.c
Normal file
@ -0,0 +1,327 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This module contains the startup code for a portable embedded
|
||||
// C/C++ application, built with newlib.
|
||||
//
|
||||
// Control reaches here from the reset handler via jump or call.
|
||||
//
|
||||
// The actual steps performed by _start are:
|
||||
// - copy the initialised data region(s)
|
||||
// - clear the BSS region(s)
|
||||
// - initialise the system
|
||||
// - run the preinit/init array (for the C++ static constructors)
|
||||
// - initialise the arc/argv
|
||||
// - branch to main()
|
||||
// - run the fini array (for the C++ static destructors)
|
||||
// - call _exit(), directly or via exit()
|
||||
//
|
||||
// If OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS is defined, the
|
||||
// code is capable of initialising multiple regions.
|
||||
//
|
||||
// The normal configuration is standalone, with all support
|
||||
// functions implemented locally.
|
||||
//
|
||||
// For this to be called, the project linker must be configured without
|
||||
// the startup sequence (-nostartfiles).
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
#define OS_INCLUDE_STARTUP_GUARD_CHECKS (1)
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
|
||||
// Begin address for the initialisation values of the .data section.
|
||||
// defined in linker script
|
||||
extern unsigned int _sidata;
|
||||
// Begin address for the .data section; defined in linker script
|
||||
extern unsigned int _sdata;
|
||||
// End address for the .data section; defined in linker script
|
||||
extern unsigned int _edata;
|
||||
|
||||
// Begin address for the .bss section; defined in linker script
|
||||
extern unsigned int __bss_start__;
|
||||
// End address for the .bss section; defined in linker script
|
||||
extern unsigned int __bss_end__;
|
||||
#else
|
||||
// The following symbols are constructs generated by the linker, indicating
|
||||
// the location of various points in the "Memory regions initialisation arrays".
|
||||
// These arrays are created by the linker via the managed linker script
|
||||
// of each RW data mechanism. It contains the load address, execution address
|
||||
// and length section and the execution and length of each BSS (zero
|
||||
// initialised) section.
|
||||
extern unsigned int __data_regions_array_start;
|
||||
extern unsigned int __data_regions_array_end;
|
||||
extern unsigned int __bss_regions_array_start;
|
||||
extern unsigned int __bss_regions_array_end;
|
||||
#endif
|
||||
|
||||
extern void
|
||||
__initialize_args (int*, char***);
|
||||
|
||||
// main() is the entry point for newlib based applications.
|
||||
// By default, there are no arguments, but this can be customised
|
||||
// by redefining __initialize_args(), which is done when the
|
||||
// semihosting configurations are used.
|
||||
extern int
|
||||
main (int argc, char* argv[]);
|
||||
|
||||
// The implementation for the exit routine; for embedded
|
||||
// applications, a system reset will be performed.
|
||||
extern void
|
||||
__attribute__((noreturn))
|
||||
_exit (int);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// Forward declarations
|
||||
|
||||
void
|
||||
_start (void);
|
||||
|
||||
void
|
||||
__initialize_data (unsigned int* from, unsigned int* region_begin,
|
||||
unsigned int* region_end);
|
||||
|
||||
void
|
||||
__initialize_bss (unsigned int* region_begin, unsigned int* region_end);
|
||||
|
||||
void
|
||||
__run_init_array (void);
|
||||
|
||||
void
|
||||
__run_fini_array (void);
|
||||
|
||||
void
|
||||
__initialize_hardware_early (void);
|
||||
|
||||
void
|
||||
__initialize_hardware (void);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
inline void
|
||||
__attribute__((always_inline))
|
||||
__initialize_data (unsigned int* from, unsigned int* region_begin,
|
||||
unsigned int* region_end)
|
||||
{
|
||||
// Iterate and copy word by word.
|
||||
// It is assumed that the pointers are word aligned.
|
||||
unsigned int *p = region_begin;
|
||||
while (p < region_end)
|
||||
*p++ = *from++;
|
||||
}
|
||||
|
||||
inline void
|
||||
__attribute__((always_inline))
|
||||
__initialize_bss (unsigned int* region_begin, unsigned int* region_end)
|
||||
{
|
||||
// Iterate and clear word by word.
|
||||
// It is assumed that the pointers are word aligned.
|
||||
unsigned int *p = region_begin;
|
||||
while (p < region_end)
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
// These magic symbols are provided by the linker.
|
||||
extern void
|
||||
(*__preinit_array_start[]) (void) __attribute__((weak));
|
||||
extern void
|
||||
(*__preinit_array_end[]) (void) __attribute__((weak));
|
||||
extern void
|
||||
(*__init_array_start[]) (void) __attribute__((weak));
|
||||
extern void
|
||||
(*__init_array_end[]) (void) __attribute__((weak));
|
||||
extern void
|
||||
(*__fini_array_start[]) (void) __attribute__((weak));
|
||||
extern void
|
||||
(*__fini_array_end[]) (void) __attribute__((weak));
|
||||
|
||||
// Iterate over all the preinit/init routines (mainly static constructors).
|
||||
inline void
|
||||
__attribute__((always_inline))
|
||||
__run_init_array (void)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = __preinit_array_end - __preinit_array_start;
|
||||
for (i = 0; i < count; i++)
|
||||
__preinit_array_start[i] ();
|
||||
|
||||
// If you need to run the code in the .init section, please use
|
||||
// the startup files, since this requires the code in crti.o and crtn.o
|
||||
// to add the function prologue/epilogue.
|
||||
//_init(); // DO NOT ENABE THIS!
|
||||
|
||||
count = __init_array_end - __init_array_start;
|
||||
for (i = 0; i < count; i++)
|
||||
__init_array_start[i] ();
|
||||
}
|
||||
|
||||
// Run all the cleanup routines (mainly static destructors).
|
||||
inline void
|
||||
__attribute__((always_inline))
|
||||
__run_fini_array (void)
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
|
||||
count = __fini_array_end - __fini_array_start;
|
||||
for (i = count; i > 0; i--)
|
||||
__fini_array_start[i - 1] ();
|
||||
|
||||
// If you need to run the code in the .fini section, please use
|
||||
// the startup files, since this requires the code in crti.o and crtn.o
|
||||
// to add the function prologue/epilogue.
|
||||
//_fini(); // DO NOT ENABE THIS!
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
|
||||
// These definitions are used to check if the routines used to
|
||||
// clear the BSS and to copy the initialised DATA perform correctly.
|
||||
|
||||
#define BSS_GUARD_BAD_VALUE (0xCADEBABA)
|
||||
|
||||
static uint32_t volatile __attribute__ ((section(".bss_begin")))
|
||||
__bss_begin_guard;
|
||||
static uint32_t volatile __attribute__ ((section(".bss_end")))
|
||||
__bss_end_guard;
|
||||
|
||||
#define DATA_GUARD_BAD_VALUE (0xCADEBABA)
|
||||
#define DATA_BEGIN_GUARD_VALUE (0x12345678)
|
||||
#define DATA_END_GUARD_VALUE (0x98765432)
|
||||
|
||||
static uint32_t volatile __attribute__ ((section(".data_begin")))
|
||||
__data_begin_guard = DATA_BEGIN_GUARD_VALUE;
|
||||
|
||||
static uint32_t volatile __attribute__ ((section(".data_end")))
|
||||
__data_end_guard = DATA_END_GUARD_VALUE;
|
||||
|
||||
#endif // defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
|
||||
// This is the place where Cortex-M core will go immediately after reset,
|
||||
// via a call or jump from the Reset_Handler.
|
||||
//
|
||||
// For the call to work, and for the call to __initialize_hardware_early()
|
||||
// to work, the reset stack must point to a valid internal RAM area.
|
||||
|
||||
void __attribute__ ((section(".after_vectors"),noreturn,weak))
|
||||
_start (void)
|
||||
{
|
||||
|
||||
// Initialise hardware right after reset, to switch clock to higher
|
||||
// frequency and have the rest of the initialisations run faster.
|
||||
//
|
||||
// Mandatory on platforms like Kinetis, which start with the watch dog
|
||||
// enabled and require an early sequence to disable it.
|
||||
//
|
||||
// Also useful on platform with external RAM, that need to be
|
||||
// initialised before filling the BSS section.
|
||||
|
||||
__initialize_hardware_early ();
|
||||
|
||||
// Use Old Style DATA and BSS section initialisation,
|
||||
// that will manage a single BSS sections.
|
||||
|
||||
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
__data_begin_guard = DATA_GUARD_BAD_VALUE;
|
||||
__data_end_guard = DATA_GUARD_BAD_VALUE;
|
||||
#endif
|
||||
|
||||
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
|
||||
// Copy the DATA segment from Flash to RAM (inlined).
|
||||
__initialize_data(&_sidata, &_sdata, &_edata);
|
||||
#else
|
||||
|
||||
// Copy the data sections from flash to SRAM.
|
||||
for (unsigned int* p = &__data_regions_array_start;
|
||||
p < &__data_regions_array_end;)
|
||||
{
|
||||
unsigned int* from = (unsigned int *) (*p++);
|
||||
unsigned int* region_begin = (unsigned int *) (*p++);
|
||||
unsigned int* region_end = (unsigned int *) (*p++);
|
||||
|
||||
__initialize_data (from, region_begin, region_end);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
if ((__data_begin_guard != DATA_BEGIN_GUARD_VALUE)
|
||||
|| (__data_end_guard != DATA_END_GUARD_VALUE))
|
||||
{
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
__bss_begin_guard = BSS_GUARD_BAD_VALUE;
|
||||
__bss_end_guard = BSS_GUARD_BAD_VALUE;
|
||||
#endif
|
||||
|
||||
#if !defined(OS_INCLUDE_STARTUP_INIT_MULTIPLE_RAM_SECTIONS)
|
||||
// Zero fill the BSS section (inlined).
|
||||
__initialize_bss(&__bss_start__, &__bss_end__);
|
||||
#else
|
||||
|
||||
// Zero fill all bss segments
|
||||
for (unsigned int *p = &__bss_regions_array_start;
|
||||
p < &__bss_regions_array_end;)
|
||||
{
|
||||
unsigned int* region_begin = (unsigned int*) (*p++);
|
||||
unsigned int* region_end = (unsigned int*) (*p++);
|
||||
__initialize_bss (region_begin, region_end);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) && (OS_INCLUDE_STARTUP_GUARD_CHECKS)
|
||||
if ((__bss_begin_guard != 0) || (__bss_end_guard != 0))
|
||||
{
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Hook to continue the initialisations. Usually compute and store the
|
||||
// clock frequency in the global CMSIS variable, cleared above.
|
||||
__initialize_hardware ();
|
||||
|
||||
// Get the argc/argv (useful in semihosting configurations).
|
||||
int argc;
|
||||
char** argv;
|
||||
__initialize_args (&argc, &argv);
|
||||
|
||||
// Call the standard library initialisation (mandatory for C++ to
|
||||
// execute the constructors for the static objects).
|
||||
__run_init_array ();
|
||||
|
||||
// Call the main entry point, and save the exit code.
|
||||
int code = main (argc, argv);
|
||||
|
||||
// Run the C++ static destructors.
|
||||
__run_fini_array ();
|
||||
|
||||
_exit (code);
|
||||
|
||||
// Should never reach this, _exit() should have already
|
||||
// performed a reset.
|
||||
for (;;)
|
||||
;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
1219
system/src/newlib/_syscalls.c
Normal file
1219
system/src/newlib/_syscalls.c
Normal file
File diff suppressed because it is too large
Load Diff
55
system/src/newlib/assert.c
Normal file
55
system/src/newlib/assert.c
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// This file is part of the µOS++ III distribution.
|
||||
// Copyright (c) 2014 Liviu Ionescu.
|
||||
//
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "diag/Trace.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
__attribute__((noreturn))
|
||||
__assert_func (const char *file, int line, const char *func,
|
||||
const char *failedexpr)
|
||||
{
|
||||
trace_printf ("assertion \"%s\" failed: file \"%s\", line %d%s%s\n",
|
||||
failedexpr, file, line, func ? ", function: " : "",
|
||||
func ? func : "");
|
||||
abort ();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is STM32 specific, but can be used on other platforms too.
|
||||
// If you need it, add the following to your application header:
|
||||
|
||||
//#ifdef USE_FULL_ASSERT
|
||||
//#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
//void assert_failed(uint8_t* file, uint32_t line);
|
||||
//#else
|
||||
//#define assert_param(expr) ((void)0)
|
||||
//#endif // USE_FULL_ASSERT
|
||||
|
||||
#if defined(USE_FULL_ASSERT)
|
||||
|
||||
void
|
||||
assert_failed (uint8_t* file, uint32_t line);
|
||||
|
||||
// Called from the assert_param() macro, usually defined in the stm32f*_conf.h
|
||||
void
|
||||
__attribute__((noreturn, weak))
|
||||
assert_failed (uint8_t* file, uint32_t line)
|
||||
{
|
||||
trace_printf ("assert_param() failed: file \"%s\", line %d\n", file, line);
|
||||
abort ();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
#endif // defined(USE_FULL_ASSERT)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
526
system/src/stm32f1xx/stm32f1xx_hal.c
Normal file
526
system/src/stm32f1xx/stm32f1xx_hal.c
Normal file
@ -0,0 +1,526 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief HAL module driver.
|
||||
* This is the common part of the HAL initialization
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
The common HAL driver contains a set of generic and common APIs that can be
|
||||
used by the PPP peripheral drivers and the user to start using the HAL.
|
||||
[..]
|
||||
The HAL contains two APIs' categories:
|
||||
(+) Common HAL APIs
|
||||
(+) Services HAL APIs
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup HAL HAL
|
||||
* @brief HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Private_Constants HAL Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief STM32F1xx HAL Driver version number
|
||||
*/
|
||||
#define __STM32F1xx_HAL_VERSION_MAIN (0x01) /*!< [31:24] main version */
|
||||
#define __STM32F1xx_HAL_VERSION_SUB1 (0x00) /*!< [23:16] sub1 version */
|
||||
#define __STM32F1xx_HAL_VERSION_SUB2 (0x04) /*!< [15:8] sub2 version */
|
||||
#define __STM32F1xx_HAL_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||
#define __STM32F1xx_HAL_VERSION ((__STM32F1xx_HAL_VERSION_MAIN << 24)\
|
||||
|(__STM32F1xx_HAL_VERSION_SUB1 << 16)\
|
||||
|(__STM32F1xx_HAL_VERSION_SUB2 << 8 )\
|
||||
|(__STM32F1xx_HAL_VERSION_RC))
|
||||
|
||||
#define IDCODE_DEVID_MASK ((uint32_t)0x00000FFF)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Private_Variables HAL Private Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
static __IO uint32_t uwTick;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup HAL_Exported_Functions HAL Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup HAL_Exported_Functions_Group1 Initialization and de-initialization Functions
|
||||
* @brief Initialization and de-initialization functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initializes the Flash interface, the NVIC allocation and initial clock
|
||||
configuration. It initializes the source of time base also when timeout
|
||||
is needed and the backup domain when enabled.
|
||||
(+) de-Initializes 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 This function configures the Flash prefetch,
|
||||
* Configures time base source, NVIC and Low level hardware
|
||||
* @note This function is called at the beginning of program after reset and before
|
||||
* the clock configuration
|
||||
* @note The time base configuration is based on MSI clock when exiting from Reset.
|
||||
* Once done, time base tick start incrementing.
|
||||
* In the default implementation,Systick is used as source of time base.
|
||||
* The tick variable is incremented each 1ms in its ISR.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_Init(void)
|
||||
{
|
||||
/* Configure Flash prefetch */
|
||||
#if (PREFETCH_ENABLE != 0)
|
||||
#if defined(STM32F101x6) || defined(STM32F101xB) || defined(STM32F101xE) || defined(STM32F101xG) || \
|
||||
defined(STM32F102x6) || defined(STM32F102xB) || \
|
||||
defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) || \
|
||||
defined(STM32F105xC) || defined(STM32F107xC)
|
||||
|
||||
/* Prefetch buffer is not available on value line devices */
|
||||
__HAL_FLASH_PREFETCH_BUFFER_ENABLE();
|
||||
#endif
|
||||
#endif /* PREFETCH_ENABLE */
|
||||
|
||||
/* Set Interrupt Group Priority */
|
||||
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
|
||||
|
||||
/* Use systick as time base source and configure 1ms tick (default clock after Reset is MSI) */
|
||||
HAL_InitTick(TICK_INT_PRIORITY);
|
||||
|
||||
/* Init the low level hardware */
|
||||
HAL_MspInit();
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
__HAL_RCC_AHB_FORCE_RESET();
|
||||
__HAL_RCC_AHB_RELEASE_RESET();
|
||||
#endif
|
||||
|
||||
/* De-Init the low level hardware */
|
||||
HAL_MspDeInit();
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes 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 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)
|
||||
{
|
||||
/*Configure the SysTick to have interrupt in 1ms time basis*/
|
||||
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
|
||||
|
||||
/*Configure the SysTick IRQ priority */
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup HAL_Exported_Functions_Group2 HAL Control functions
|
||||
* @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
|
||||
(+) Enable/Disable Debug module during Sleep mode
|
||||
(+) Enable/Disable Debug module during STOP mode
|
||||
(+) Enable/Disable Debug module during STANDBY mode
|
||||
|
||||
@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++;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 provides accurate 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(__IO uint32_t Delay)
|
||||
{
|
||||
uint32_t tickstart = 0;
|
||||
tickstart = HAL_GetTick();
|
||||
while((HAL_GetTick() - tickstart) < Delay)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 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 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 This method returns the HAL revision
|
||||
* @retval version: 0xXYZR (8bits for each decimal, R for RC)
|
||||
*/
|
||||
uint32_t HAL_GetHalVersion(void)
|
||||
{
|
||||
return __STM32F1xx_HAL_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device revision identifier.
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval Device revision identifier
|
||||
*/
|
||||
uint32_t HAL_GetREVID(void)
|
||||
{
|
||||
return((DBGMCU->IDCODE) >> POSITION_VAL(DBGMCU_IDCODE_REV_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the device identifier.
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval Device identifier
|
||||
*/
|
||||
uint32_t HAL_GetDEVID(void)
|
||||
{
|
||||
return((DBGMCU->IDCODE) & IDCODE_DEVID_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during SLEEP mode
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGSleepMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during SLEEP mode
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGSleepMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STOP mode
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* Note: On all STM32F1 devices:
|
||||
* If the system tick timer interrupt is enabled during the Stop mode
|
||||
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
||||
* the system from Stop mode.
|
||||
* Workaround: To debug the Stop mode, disable the system tick timer
|
||||
* interrupt.
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* Note: On all STM32F1 devices:
|
||||
* If the system tick timer interrupt is enabled during the Stop mode
|
||||
* debug (DBG_STOP bit set in the DBGMCU_CR register ), it will wakeup
|
||||
* the system from Stop mode.
|
||||
* Workaround: To debug the Stop mode, disable the system tick timer
|
||||
* interrupt.
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStopMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STOP mode
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStopMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the Debug Module during STANDBY mode
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_EnableDBGStandbyMode(void)
|
||||
{
|
||||
SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the Debug Module during STANDBY mode
|
||||
* Note: On devices STM32F10xx8 and STM32F10xxB,
|
||||
* STM32F101xC/D/E and STM32F103xC/D/E,
|
||||
* STM32F101xF/G and STM32F103xF/G
|
||||
* STM32F10xx4 and STM32F10xx6
|
||||
* Debug registers DBGMCU_IDCODE and DBGMCU_CR are accessible only in
|
||||
* debug mode (not accessible by the user software in normal mode).
|
||||
* Refer to errata sheet of these devices for more details.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DBGMCU_DisableDBGStandbyMode(void)
|
||||
{
|
||||
CLEAR_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STANDBY);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
2112
system/src/stm32f1xx/stm32f1xx_hal_adc.c
Normal file
2112
system/src/stm32f1xx/stm32f1xx_hal_adc.c
Normal file
File diff suppressed because it is too large
Load Diff
1365
system/src/stm32f1xx/stm32f1xx_hal_adc_ex.c
Normal file
1365
system/src/stm32f1xx/stm32f1xx_hal_adc_ex.c
Normal file
File diff suppressed because it is too large
Load Diff
494
system/src/stm32f1xx/stm32f1xx_hal_cortex.c
Normal file
494
system/src/stm32f1xx/stm32f1xx_hal_cortex.c
Normal file
@ -0,0 +1,494 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_cortex.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief CORTEX HAL module driver.
|
||||
*
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the CORTEX:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
* @verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
|
||||
[..]
|
||||
*** How to configure Interrupts using Cortex HAL driver ***
|
||||
===========================================================
|
||||
[..]
|
||||
This section provide functions allowing to configure the NVIC interrupts (IRQ).
|
||||
The Cortex-M3 exceptions are managed by CMSIS functions.
|
||||
|
||||
(#) Configure the NVIC Priority Grouping using HAL_NVIC_SetPriorityGrouping()
|
||||
function according to the following table.
|
||||
|
||||
The table below gives the allowed values of the pre-emption priority and subpriority according
|
||||
to the Priority Grouping configuration performed by HAL_NVIC_SetPriorityGrouping() function.
|
||||
==========================================================================================================================
|
||||
NVIC_PriorityGroup | NVIC_IRQChannelPreemptionPriority | NVIC_IRQChannelSubPriority | Description
|
||||
==========================================================================================================================
|
||||
NVIC_PRIORITYGROUP_0 | 0 | 0-15 | 0 bits for pre-emption priority
|
||||
| | | 4 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_1 | 0-1 | 0-7 | 1 bits for pre-emption priority
|
||||
| | | 3 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_2 | 0-3 | 0-3 | 2 bits for pre-emption priority
|
||||
| | | 2 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_3 | 0-7 | 0-1 | 3 bits for pre-emption priority
|
||||
| | | 1 bits for subpriority
|
||||
--------------------------------------------------------------------------------------------------------------------------
|
||||
NVIC_PRIORITYGROUP_4 | 0-15 | 0 | 4 bits for pre-emption priority
|
||||
| | | 0 bits for subpriority
|
||||
==========================================================================================================================
|
||||
(#) Configure the priority of the selected IRQ Channels using HAL_NVIC_SetPriority()
|
||||
|
||||
(#) Enable the selected IRQ Channels using HAL_NVIC_EnableIRQ()
|
||||
|
||||
|
||||
-@- When the NVIC_PRIORITYGROUP_0 is selected, IRQ pre-emption is no more possible.
|
||||
The pending IRQ priority will be managed only by the sub priority.
|
||||
|
||||
-@- IRQ priority order (sorted by highest to lowest priority):
|
||||
(+@) Lowest pre-emption priority
|
||||
(+@) Lowest sub priority
|
||||
(+@) Lowest hardware priority (IRQ number)
|
||||
|
||||
[..]
|
||||
*** How to configure Systick using Cortex HAL driver ***
|
||||
========================================================
|
||||
[..]
|
||||
Setup SysTick Timer for 1 msec interrupts.
|
||||
|
||||
(+) 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 (0x0F).
|
||||
(++) 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 function
|
||||
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK_DIV8) just after the
|
||||
HAL_SYSTICK_Config() function call.
|
||||
|
||||
(+) You can change the SysTick IRQ priority by calling the
|
||||
HAL_NVIC_SetPriority(SysTick_IRQn,...) function just after the HAL_SYSTICK_Config() function
|
||||
call. The HAL_NVIC_SetPriority() call the NVIC_SetPriority() function which is a CMSIS function.
|
||||
|
||||
(+) To adjust the SysTick time base, use the following formula:
|
||||
|
||||
Reload Value = SysTick Counter Clock (Hz) x Desired Time base (s)
|
||||
(++) Reload Value is the parameter to be passed for HAL_SYSTICK_Config() function
|
||||
(++) Reload Value should not exceed 0xFFFFFF
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CORTEX CORTEX
|
||||
* @brief CORTEX HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CORTEX_Exported_Functions CORTEX Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup CORTEX_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This section provide the Cortex HAL driver functions allowing to configure Interrupts
|
||||
Systick functionalities
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sets the priority grouping field (pre-emption priority and subpriority)
|
||||
* using the required unlock sequence.
|
||||
* @param PriorityGroup: The priority grouping bits length.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg NVIC_PRIORITYGROUP_0: 0 bits for pre-emption priority
|
||||
* 4 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_1: 1 bits for pre-emption priority
|
||||
* 3 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority
|
||||
* 2 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority
|
||||
* 1 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority
|
||||
* 0 bits for subpriority
|
||||
* @note When the NVIC_PriorityGroup_0 is selected, IRQ pre-emption is no more possible.
|
||||
* The pending IRQ priority will be managed only by the subpriority.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||
|
||||
/* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
|
||||
NVIC_SetPriorityGrouping(PriorityGroup);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the priority of an interrupt.
|
||||
* @param IRQn: External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @param PreemptPriority: The pre-emption priority for the IRQn channel.
|
||||
* This parameter can be a value between 0 and 15
|
||||
* A lower priority value indicates a higher priority
|
||||
* @param SubPriority: the subpriority level for the IRQ channel.
|
||||
* This parameter can be a value between 0 and 15
|
||||
* A lower priority value indicates a higher priority.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t prioritygroup = 0x00;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_SUB_PRIORITY(SubPriority));
|
||||
assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
|
||||
|
||||
prioritygroup = NVIC_GetPriorityGrouping();
|
||||
|
||||
NVIC_SetPriority(IRQn, NVIC_EncodePriority(prioritygroup, PreemptPriority, SubPriority));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
* @note To configure interrupts priority correctly, the NVIC_PriorityGroupConfig()
|
||||
* function should be called before.
|
||||
* @param IRQn External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @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 Disables 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 STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.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 Initiates a system reset request to reset the MCU.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SystemReset(void)
|
||||
{
|
||||
/* System Reset */
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
* 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);
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CORTEX_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if (__MPU_PRESENT == 1)
|
||||
/**
|
||||
* @brief Initializes and configures the Region and the memory to be protected.
|
||||
* @param MPU_Init: Pointer to a MPU_Region_InitTypeDef structure that contains
|
||||
* the initialization and configuration information.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_MPU_ConfigRegion(MPU_Region_InitTypeDef *MPU_Init)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_REGION_NUMBER(MPU_Init->Number));
|
||||
assert_param(IS_MPU_REGION_ENABLE(MPU_Init->Enable));
|
||||
|
||||
/* Set the Region number */
|
||||
MPU->RNR = MPU_Init->Number;
|
||||
|
||||
if ((MPU_Init->Enable) != RESET)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_MPU_INSTRUCTION_ACCESS(MPU_Init->DisableExec));
|
||||
assert_param(IS_MPU_REGION_PERMISSION_ATTRIBUTE(MPU_Init->AccessPermission));
|
||||
assert_param(IS_MPU_TEX_LEVEL(MPU_Init->TypeExtField));
|
||||
assert_param(IS_MPU_ACCESS_SHAREABLE(MPU_Init->IsShareable));
|
||||
assert_param(IS_MPU_ACCESS_CACHEABLE(MPU_Init->IsCacheable));
|
||||
assert_param(IS_MPU_ACCESS_BUFFERABLE(MPU_Init->IsBufferable));
|
||||
assert_param(IS_MPU_SUB_REGION_DISABLE(MPU_Init->SubRegionDisable));
|
||||
assert_param(IS_MPU_REGION_SIZE(MPU_Init->Size));
|
||||
|
||||
MPU->RBAR = MPU_Init->BaseAddress;
|
||||
MPU->RASR = ((uint32_t)MPU_Init->DisableExec << MPU_RASR_XN_Pos) |
|
||||
((uint32_t)MPU_Init->AccessPermission << MPU_RASR_AP_Pos) |
|
||||
((uint32_t)MPU_Init->TypeExtField << MPU_RASR_TEX_Pos) |
|
||||
((uint32_t)MPU_Init->IsShareable << MPU_RASR_S_Pos) |
|
||||
((uint32_t)MPU_Init->IsCacheable << MPU_RASR_C_Pos) |
|
||||
((uint32_t)MPU_Init->IsBufferable << MPU_RASR_B_Pos) |
|
||||
((uint32_t)MPU_Init->SubRegionDisable << MPU_RASR_SRD_Pos) |
|
||||
((uint32_t)MPU_Init->Size << MPU_RASR_SIZE_Pos) |
|
||||
((uint32_t)MPU_Init->Enable << MPU_RASR_ENABLE_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
MPU->RBAR = 0x00;
|
||||
MPU->RASR = 0x00;
|
||||
}
|
||||
}
|
||||
#endif /* __MPU_PRESENT */
|
||||
|
||||
/**
|
||||
* @brief Gets the priority grouping field from the NVIC Interrupt Controller.
|
||||
* @retval Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field)
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetPriorityGrouping(void)
|
||||
{
|
||||
/* Get the PRIGROUP[10:8] field value */
|
||||
return NVIC_GetPriorityGrouping();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the priority of an interrupt.
|
||||
* @param IRQn: External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @param PriorityGroup: the priority grouping bits length.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg NVIC_PRIORITYGROUP_0: 0 bits for pre-emption priority
|
||||
* 4 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_1: 1 bits for pre-emption priority
|
||||
* 3 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_2: 2 bits for pre-emption priority
|
||||
* 2 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_3: 3 bits for pre-emption priority
|
||||
* 1 bits for subpriority
|
||||
* @arg NVIC_PRIORITYGROUP_4: 4 bits for pre-emption priority
|
||||
* 0 bits for subpriority
|
||||
* @param pPreemptPriority: Pointer on the Preemptive priority value (starting from 0).
|
||||
* @param pSubPriority: Pointer on the Subpriority value (starting from 0).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_GetPriority(IRQn_Type IRQn, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));
|
||||
/* Get priority for Cortex-M system or device specific interrupts */
|
||||
NVIC_DecodePriority(NVIC_GetPriority(IRQn), PriorityGroup, pPreemptPriority, pSubPriority);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets Pending bit of an external interrupt.
|
||||
* @param IRQn External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Set interrupt pending */
|
||||
NVIC_SetPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets Pending Interrupt (reads the pending register in the NVIC
|
||||
* and returns 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 STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @retval status: - 0 Interrupt status is not pending.
|
||||
* - 1 Interrupt status is pending.
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Return 1 if pending else 0 */
|
||||
return NVIC_GetPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clears 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 STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
/* Clear pending interrupt */
|
||||
NVIC_ClearPendingIRQ(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets active interrupt ( reads the active register in NVIC and returns the active bit).
|
||||
* @param IRQn External interrupt number
|
||||
* This parameter can be an enumerator of IRQn_Type enumeration
|
||||
* (For the complete STM32 Devices IRQ Channels list, please refer to the appropriate CMSIS device file (stm32f10xxx.h))
|
||||
* @retval status: - 0 Interrupt status is not pending.
|
||||
* - 1 Interrupt status is pending.
|
||||
*/
|
||||
uint32_t HAL_NVIC_GetActive(IRQn_Type IRQn)
|
||||
{
|
||||
/* Return 1 if active else 0 */
|
||||
return NVIC_GetActive(IRQn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures 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 This function handles 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 STMicroelectronics *****END OF FILE****/
|
709
system/src/stm32f1xx/stm32f1xx_hal_dma.c
Normal file
709
system/src/stm32f1xx/stm32f1xx_hal_dma.c
Normal file
@ -0,0 +1,709 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_dma.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief DMA HAL module driver.
|
||||
*
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Direct Memory Access (DMA) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + IO operation functions
|
||||
* + Peripheral State and errors functions
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Enable and configure the peripheral to be connected to the DMA Channel
|
||||
(except for internal SRAM / FLASH memories: no initialization is
|
||||
necessary) please refer to Reference manual for connection between peripherals
|
||||
and DMA requests.
|
||||
|
||||
(#) For a given Channel, program the required configuration through the following parameters:
|
||||
Transfer Direction, Source and Destination data formats,
|
||||
Circular or Normal mode, Channel Priority level, Source and Destination Increment mode,
|
||||
using HAL_DMA_Init() function.
|
||||
|
||||
(#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
|
||||
detection.
|
||||
|
||||
(#) Use HAL_DMA_Abort() function to abort the current transfer
|
||||
|
||||
-@- In Memory-to-Memory transfer mode, Circular mode is not allowed.
|
||||
*** Polling mode IO operation ***
|
||||
=================================
|
||||
[..]
|
||||
(+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
|
||||
address and destination address and the Length of data to be transferred
|
||||
(+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
|
||||
case a fixed Timeout can be configured by User depending from his application.
|
||||
|
||||
*** Interrupt mode IO operation ***
|
||||
===================================
|
||||
[..]
|
||||
(+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
|
||||
(+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
|
||||
(+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
|
||||
Source address and destination address and the Length of data to be transferred.
|
||||
In this case the DMA interrupt is configured
|
||||
(+) Use HAL_DMAy_Channelx_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
|
||||
(+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
|
||||
add his own function by customization of function pointer XferCpltCallback and
|
||||
XferErrorCallback (i.e a member of DMA handle structure).
|
||||
|
||||
*** DMA HAL driver macros list ***
|
||||
=============================================
|
||||
[..]
|
||||
Below the list of most used macros in DMA HAL driver.
|
||||
|
||||
(+) __HAL_DMA_ENABLE: Enable the specified DMA Channel.
|
||||
(+) __HAL_DMA_DISABLE: Disable the specified DMA Channel.
|
||||
(+) __HAL_DMA_GET_FLAG: Get the DMA Channel pending flags.
|
||||
(+) __HAL_DMA_CLEAR_FLAG: Clear the DMA Channel pending flags.
|
||||
(+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Channel interrupts.
|
||||
(+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Channel interrupts.
|
||||
(+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Channel interrupt has occurred or not.
|
||||
|
||||
[..]
|
||||
(@) You can refer to the DMA HAL driver header file for more useful macros
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DMA DMA
|
||||
* @brief DMA HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup DMA_Private_Constants DMA Private Constants
|
||||
* @{
|
||||
*/
|
||||
#define HAL_TIMEOUT_DMA_ABORT ((uint32_t)1000) /* 1s */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup DMA_Private_Functions DMA Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions DMA Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and de-initialization functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to initialize the DMA Channel source
|
||||
and destination addresses, incrementation and data sizes, transfer direction,
|
||||
circular/normal mode selection, memory-to-memory mode selection and Channel priority value.
|
||||
[..]
|
||||
The HAL_DMA_Init() function follows the DMA configuration procedures as described in
|
||||
reference manual.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the DMA according to the specified
|
||||
* parameters in the DMA_InitTypeDef and create the associated handle.
|
||||
* @param hdma: Pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
|
||||
/* Check the DMA handle allocation */
|
||||
if(hdma == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
|
||||
assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
|
||||
assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
|
||||
assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
|
||||
assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
|
||||
assert_param(IS_DMA_MODE(hdma->Init.Mode));
|
||||
assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
|
||||
|
||||
if(hdma->State == HAL_DMA_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hdma->Lock = HAL_UNLOCKED;
|
||||
}
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
|
||||
/* Get the CR register value */
|
||||
tmp = hdma->Instance->CCR;
|
||||
|
||||
/* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR bits */
|
||||
tmp &= ((uint32_t)~(DMA_CCR_PL | DMA_CCR_MSIZE | DMA_CCR_PSIZE | \
|
||||
DMA_CCR_MINC | DMA_CCR_PINC | DMA_CCR_CIRC | \
|
||||
DMA_CCR_DIR));
|
||||
|
||||
/* Prepare the DMA Channel configuration */
|
||||
tmp |= hdma->Init.Direction |
|
||||
hdma->Init.PeriphInc | hdma->Init.MemInc |
|
||||
hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
|
||||
hdma->Init.Mode | hdma->Init.Priority;
|
||||
|
||||
/* Write to DMA Channel CR register */
|
||||
hdma->Instance->CCR = tmp;
|
||||
|
||||
/* Initialise the error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Initialize the DMA state*/
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitializes the DMA peripheral
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Check the DMA handle allocation */
|
||||
if(hdma == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
|
||||
|
||||
/* Check the DMA peripheral state */
|
||||
if(hdma->State == HAL_DMA_STATE_BUSY)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Disable the selected DMA Channelx */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Reset DMA Channel control register */
|
||||
hdma->Instance->CCR = 0;
|
||||
|
||||
/* Reset DMA Channel Number of Data to Transfer register */
|
||||
hdma->Instance->CNDTR = 0;
|
||||
|
||||
/* Reset DMA Channel peripheral address register */
|
||||
hdma->Instance->CPAR = 0;
|
||||
|
||||
/* Reset DMA Channel memory address register */
|
||||
hdma->Instance->CMAR = 0;
|
||||
|
||||
/* Clear all flags */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||
|
||||
/* Initialize the error code */
|
||||
hdma->ErrorCode = HAL_DMA_ERROR_NONE;
|
||||
|
||||
/* Initialize the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_RESET;
|
||||
|
||||
/* Release Lock */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group2 Input and Output operation functions
|
||||
* @brief I/O operation functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure the source, destination address and data length and Start DMA transfer
|
||||
(+) Configure the source, destination address and data length and
|
||||
Start DMA transfer with interrupt
|
||||
(+) Abort DMA transfer
|
||||
(+) Poll for transfer complete
|
||||
(+) Handle DMA interrupt request
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Starts the DMA Transfer.
|
||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Configure the source, destination address and the data length */
|
||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_DMA_ENABLE(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start the DMA Transfer with interrupt enabled.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
/* Process locked */
|
||||
__HAL_LOCK(hdma);
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_BUSY;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_DMA_BUFFER_SIZE(DataLength));
|
||||
|
||||
/* Disable the peripheral */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Configure the source, destination address and the data length */
|
||||
DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
|
||||
|
||||
/* Enable the transfer complete interrupt */
|
||||
__HAL_DMA_ENABLE_IT(hdma, DMA_IT_TC);
|
||||
|
||||
/* Enable the Half transfer complete interrupt */
|
||||
__HAL_DMA_ENABLE_IT(hdma, DMA_IT_HT);
|
||||
|
||||
/* Enable the transfer Error interrupt */
|
||||
__HAL_DMA_ENABLE_IT(hdma, DMA_IT_TE);
|
||||
|
||||
/* Enable the Peripheral */
|
||||
__HAL_DMA_ENABLE(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Aborts the DMA Transfer.
|
||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
*
|
||||
* @note After disabling a DMA Channel, a check for wait until the DMA Channel is
|
||||
* effectively disabled is added. If a Channel is disabled
|
||||
* while a data transfer is ongoing, the current data will be transferred
|
||||
* and the Channel will be effectively disabled only after the transfer of
|
||||
* this single data is finished.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
uint32_t tickstart = 0x00;
|
||||
|
||||
/* Disable the channel */
|
||||
__HAL_DMA_DISABLE(hdma);
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Check if the DMA Channel is effectively disabled */
|
||||
while((hdma->Instance->CCR & DMA_CCR_EN) != 0)
|
||||
{
|
||||
/* Check for the Timeout */
|
||||
if((HAL_GetTick() - tickstart) > HAL_TIMEOUT_DMA_ABORT)
|
||||
{
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_TIMEOUT;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polling for transfer complete.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param CompleteLevel: Specifies the DMA level complete.
|
||||
* @param Timeout: Timeout duration.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, uint32_t CompleteLevel, uint32_t Timeout)
|
||||
{
|
||||
uint32_t temp;
|
||||
uint32_t tickstart = 0x00;
|
||||
|
||||
/* Get the level transfer complete flag */
|
||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
||||
{
|
||||
/* Transfer Complete flag */
|
||||
temp = __HAL_DMA_GET_TC_FLAG_INDEX(hdma);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Half Transfer Complete flag */
|
||||
temp = __HAL_DMA_GET_HT_FLAG_INDEX(hdma);
|
||||
}
|
||||
|
||||
/* Get tick */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while(__HAL_DMA_GET_FLAG(hdma, temp) == RESET)
|
||||
{
|
||||
if((__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET))
|
||||
{
|
||||
/* Clear the transfer error flags */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
||||
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State= HAL_DMA_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
/* Check for the Timeout */
|
||||
if(Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0) || ((HAL_GetTick() - tickstart) > Timeout))
|
||||
{
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TIMEOUT);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_TIMEOUT;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
|
||||
{
|
||||
/* Clear the transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||
|
||||
/* The selected Channelx EN bit is cleared (DMA is disabled and
|
||||
all transfers are complete) */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear the half transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||
|
||||
/* The selected Channelx EN bit is cleared (DMA is disabled and
|
||||
all transfers of half buffer are complete) */
|
||||
hdma->State = HAL_DMA_STATE_READY_HALF;
|
||||
}
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handles DMA interrupt request.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
/* Transfer Error Interrupt management ***************************************/
|
||||
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma)) != RESET)
|
||||
{
|
||||
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != RESET)
|
||||
{
|
||||
/* Disable the transfer error interrupt */
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE);
|
||||
|
||||
/* Clear the transfer error flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TE_FLAG_INDEX(hdma));
|
||||
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_TE);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_ERROR;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
if (hdma->XferErrorCallback != NULL)
|
||||
{
|
||||
/* Transfer error callback */
|
||||
hdma->XferErrorCallback(hdma);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Half Transfer Complete Interrupt management ******************************/
|
||||
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma)) != RESET)
|
||||
{
|
||||
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != RESET)
|
||||
{
|
||||
/* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
|
||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
|
||||
{
|
||||
/* Disable the half transfer interrupt */
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
|
||||
}
|
||||
/* Clear the half transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_HT_FLAG_INDEX(hdma));
|
||||
|
||||
/* Change DMA peripheral state */
|
||||
hdma->State = HAL_DMA_STATE_READY_HALF;
|
||||
|
||||
if(hdma->XferHalfCpltCallback != NULL)
|
||||
{
|
||||
/* Half transfer callback */
|
||||
hdma->XferHalfCpltCallback(hdma);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer Complete Interrupt management ***********************************/
|
||||
if(__HAL_DMA_GET_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma)) != RESET)
|
||||
{
|
||||
if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != RESET)
|
||||
{
|
||||
if((hdma->Instance->CCR & DMA_CCR_CIRC) == 0)
|
||||
{
|
||||
/* Disable the transfer complete interrupt */
|
||||
__HAL_DMA_DISABLE_IT(hdma, DMA_IT_TC);
|
||||
}
|
||||
/* Clear the transfer complete flag */
|
||||
__HAL_DMA_CLEAR_FLAG(hdma, __HAL_DMA_GET_TC_FLAG_INDEX(hdma));
|
||||
|
||||
/* Update error code */
|
||||
SET_BIT(hdma->ErrorCode, HAL_DMA_ERROR_NONE);
|
||||
|
||||
/* Change the DMA state */
|
||||
hdma->State = HAL_DMA_STATE_READY;
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(hdma);
|
||||
|
||||
if(hdma->XferCpltCallback != NULL)
|
||||
{
|
||||
/* Transfer complete callback */
|
||||
hdma->XferCpltCallback(hdma);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup DMA_Exported_Functions_Group3 Peripheral State functions
|
||||
* @brief Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### State and Errors functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides functions allowing to
|
||||
(+) Check the DMA state
|
||||
(+) Get error code
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Returns the DMA state.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_DMA_StateTypeDef HAL_DMA_GetState(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
return hdma->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the DMA error code
|
||||
* @param hdma : pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @retval DMA Error Code
|
||||
*/
|
||||
uint32_t HAL_DMA_GetError(DMA_HandleTypeDef *hdma)
|
||||
{
|
||||
return hdma->ErrorCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup DMA_Private_Functions DMA Private Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Sets the DMA Transfer parameter.
|
||||
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
|
||||
* the configuration information for the specified DMA Channel.
|
||||
* @param SrcAddress: The source memory Buffer address
|
||||
* @param DstAddress: The destination memory Buffer address
|
||||
* @param DataLength: The length of data to be transferred from source to destination
|
||||
* @retval HAL status
|
||||
*/
|
||||
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
|
||||
{
|
||||
/* Configure DMA Channel data length */
|
||||
hdma->Instance->CNDTR = DataLength;
|
||||
|
||||
/* Peripheral to Memory */
|
||||
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
|
||||
{
|
||||
/* Configure DMA Channel destination address */
|
||||
hdma->Instance->CPAR = DstAddress;
|
||||
|
||||
/* Configure DMA Channel source address */
|
||||
hdma->Instance->CMAR = SrcAddress;
|
||||
}
|
||||
/* Memory to Peripheral */
|
||||
else
|
||||
{
|
||||
/* Configure DMA Channel source address */
|
||||
hdma->Instance->CPAR = SrcAddress;
|
||||
|
||||
/* Configure DMA Channel destination address */
|
||||
hdma->Instance->CMAR = DstAddress;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
974
system/src/stm32f1xx/stm32f1xx_hal_flash.c
Normal file
974
system/src/stm32f1xx/stm32f1xx_hal_flash.c
Normal file
@ -0,0 +1,974 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_flash.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @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 State functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### FLASH peripheral features #####
|
||||
==============================================================================
|
||||
[..] The Flash memory interface manages CPU AHB I-Code and D-Code accesses
|
||||
to the Flash memory. It implements the erase and program Flash memory operations
|
||||
and the read and write protection mechanisms.
|
||||
|
||||
[..] The Flash memory interface accelerates code execution with a system of instruction
|
||||
prefetch.
|
||||
|
||||
[..] The FLASH main features are:
|
||||
(+) Flash memory read operations
|
||||
(+) Flash memory program/erase operations
|
||||
(+) Read / write protections
|
||||
(+) Prefetch on I-Code
|
||||
(+) Option Bytes programming
|
||||
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
This driver provides functions and macros to configure and program the FLASH
|
||||
memory of all STM32F1xx devices.
|
||||
|
||||
(#) FLASH Memory I/O Programming functions: this group includes all needed
|
||||
functions to erase and program the main memory:
|
||||
(++) Lock and Unlock the FLASH interface
|
||||
(++) Erase function: Erase page, erase all pages
|
||||
(++) Program functions: half word, word and doubleword
|
||||
|
||||
(#) FLASH Option Bytes Programming functions: this group includes all needed
|
||||
functions to manage the Option Bytes:
|
||||
(++) Lock and Unlock the Option Bytes
|
||||
(++) Set/Reset the write protection
|
||||
(++) Set the Read protection Level
|
||||
(++) Program the user Option Bytes
|
||||
(++) Launch the Option Bytes loader
|
||||
(++) Erase Option Bytes
|
||||
(++) Program the data Option Bytes
|
||||
(++) Get the Write protection.
|
||||
(++) Get the user option bytes.
|
||||
|
||||
(#) Interrupts and flags management functions : this group
|
||||
includes all needed functions to:
|
||||
(++) Handle FLASH interrupts
|
||||
(++) Wait for last FLASH operation according to its status
|
||||
(++) Get error flag status
|
||||
|
||||
[..] In addition to these function, this driver includes a set of macros allowing
|
||||
to handle the following operations:
|
||||
|
||||
(+) Set/Get the latency
|
||||
(+) Enable/Disable the prefetch buffer
|
||||
(+) Enable/Disable the half cycle access
|
||||
(+) Enable/Disable the FLASH interrupts
|
||||
(+) Monitor the FLASH flags status
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
|
||||
/** @defgroup FLASH FLASH
|
||||
* @brief FLASH HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Constants FLASH Private Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro ---------------------------- ---------------------------------*/
|
||||
/** @defgroup FLASH_Private_Macros FLASH Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Variables FLASH Private Variables
|
||||
* @{
|
||||
*/
|
||||
/* Variables used for Erase pages under interruption*/
|
||||
FLASH_ProcessTypeDef pFlash;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup FLASH_Private_Functions FLASH Private Functions
|
||||
* @{
|
||||
*/
|
||||
static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data);
|
||||
static void FLASH_SetErrorCode(void);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions ---------------------------------------------------------*/
|
||||
/** @defgroup FLASH_Exported_Functions FLASH Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Exported_Functions_Group1 Programming operation functions
|
||||
* @brief Programming operation functions
|
||||
*
|
||||
@verbatim
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Program halfword, word or double word at a specified address
|
||||
* @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
|
||||
* The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
|
||||
*
|
||||
* @note If an erase and a program operations are requested simultaneously,
|
||||
* the erase operation is performed before the program one.
|
||||
*
|
||||
* @note FLASH should be previously erased before new programmation (only exception to this
|
||||
* is when 0x0000 is programmed)
|
||||
*
|
||||
* @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 Data: Specifies the data to be programmed
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_ERROR;
|
||||
uint8_t index = 0;
|
||||
uint8_t nbiterations = 0;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(Address <= FLASH_BANK1_END)
|
||||
{
|
||||
#endif /* FLASH_BANK2_END */
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
#if defined(FLASH_BANK2_END)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
}
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
if(status == HAL_OK)
|
||||
{
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
|
||||
{
|
||||
/* Program halfword (16-bit) at a specified address. */
|
||||
nbiterations = 1;
|
||||
}
|
||||
else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
|
||||
{
|
||||
/* Program word (32-bit = 2*16-bit) at a specified address. */
|
||||
nbiterations = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Program double word (64-bit = 4*16-bit) at a specified address. */
|
||||
nbiterations = 4;
|
||||
}
|
||||
|
||||
for (index = 0; index < nbiterations; index++)
|
||||
{
|
||||
FLASH_Program_HalfWord((Address + (2*index)), (uint16_t)(Data >> (16*index)));
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(Address <= FLASH_BANK1_END)
|
||||
{
|
||||
#endif /* FLASH_BANK2_END */
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the program operation is completed, disable the PG Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
#if defined(FLASH_BANK2_END)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wait for last operation to be completed */
|
||||
status = FLASH_WaitForLastOperationBank2((uint32_t)FLASH_TIMEOUT_VALUE);
|
||||
|
||||
/* If the program operation is completed, disable the PG Bit */
|
||||
CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
|
||||
}
|
||||
#endif /* FLASH_BANK2_END */
|
||||
/* In case of error, stop programation procedure */
|
||||
if (status != HAL_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Process Unlocked */
|
||||
__HAL_UNLOCK(&pFlash);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Program halfword, word or double word at a specified address with interrupt enabled.
|
||||
* @note The function HAL_FLASH_Unlock() should be called before to unlock the FLASH interface
|
||||
* The function HAL_FLASH_Lock() should be called after to lock the FLASH interface
|
||||
*
|
||||
* @note If an erase and a program operations are requested simultaneously,
|
||||
* the erase operation is performed before the program one.
|
||||
*
|
||||
* @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 Data: Specifies the data to be programmed
|
||||
*
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Program_IT(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
|
||||
{
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
/* Process Locked */
|
||||
__HAL_LOCK(&pFlash);
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
|
||||
assert_param(IS_FLASH_PROGRAM_ADDRESS(Address));
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/* If procedure already ongoing, reject the next one */
|
||||
if (pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if(Address <= FLASH_BANK1_END)
|
||||
{
|
||||
/* Enable End of FLASH Operation and Error source interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1);
|
||||
|
||||
}else
|
||||
{
|
||||
/* Enable End of FLASH Operation and Error source interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
|
||||
}
|
||||
#else
|
||||
/* Enable End of FLASH Operation and Error source interrupts */
|
||||
__HAL_FLASH_ENABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
pFlash.Address = Address;
|
||||
pFlash.Data = Data;
|
||||
|
||||
if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
|
||||
{
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMHALFWORD;
|
||||
/*Program halfword (16-bit) at a specified address.*/
|
||||
pFlash.DataRemaining = 1;
|
||||
}
|
||||
else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
|
||||
{
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMWORD;
|
||||
/*Program word (32-bit : 2*16-bit) at a specified address.*/
|
||||
pFlash.DataRemaining = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_PROGRAMDOUBLEWORD;
|
||||
/*Program double word (64-bit : 4*16-bit) at a specified address.*/
|
||||
pFlash.DataRemaining = 4;
|
||||
}
|
||||
|
||||
/*Program halfword (16-bit) at a specified address.*/
|
||||
FLASH_Program_HalfWord(Address, (uint16_t)Data);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles FLASH interrupt request.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_FLASH_IRQHandler(void)
|
||||
{
|
||||
uint32_t addresstmp = 0;
|
||||
|
||||
/* Check FLASH operation error flags */
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK1) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK1) || \
|
||||
(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2)))
|
||||
#else
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
|
||||
#endif /* FLASH_BANK2_END */
|
||||
{
|
||||
/*return the faulty address*/
|
||||
addresstmp = pFlash.Address;
|
||||
/* Reset address */
|
||||
pFlash.Address = 0xFFFFFFFF;
|
||||
|
||||
/*Save the Error code*/
|
||||
FLASH_SetErrorCode();
|
||||
|
||||
/* FLASH error interrupt user callback */
|
||||
HAL_FLASH_OperationErrorCallback(addresstmp);
|
||||
|
||||
/* Stop the procedure ongoing*/
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
|
||||
/* Check FLASH End of Operation flag */
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK1))
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK1);
|
||||
#else
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
/* Process can continue only if no error detected */
|
||||
if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
|
||||
{
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
|
||||
{
|
||||
/* Nb of pages to erased can be decreased */
|
||||
pFlash.DataRemaining--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if(pFlash.DataRemaining != 0)
|
||||
{
|
||||
addresstmp = pFlash.Address;
|
||||
/*Indicate user which sector has been erased*/
|
||||
HAL_FLASH_EndOfOperationCallback(addresstmp);
|
||||
|
||||
/*Increment sector number*/
|
||||
addresstmp = pFlash.Address + FLASH_PAGE_SIZE;
|
||||
pFlash.Address = addresstmp;
|
||||
|
||||
/* If the erase operation is completed, disable the PER Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PER);
|
||||
|
||||
FLASH_PageErase(addresstmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*No more pages to Erase, user callback can be called.*/
|
||||
/*Reset Sector and stop Erase pages procedure*/
|
||||
pFlash.Address = addresstmp = 0xFFFFFFFF;
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(addresstmp);
|
||||
}
|
||||
}
|
||||
else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
|
||||
{
|
||||
/* Operation is completed, disable the MER Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_MER);
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/* Stop Mass Erase procedure if no pending mass erase on other bank */
|
||||
if (HAL_IS_BIT_CLR(FLASH->CR2, FLASH_CR2_MER))
|
||||
{
|
||||
#endif /* FLASH_BANK2_END */
|
||||
/* MassErase ended. Return the selected bank*/
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(0);
|
||||
|
||||
/* Stop Mass Erase procedure*/
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
#if defined(FLASH_BANK2_END)
|
||||
}
|
||||
#endif /* FLASH_BANK2_END */
|
||||
else
|
||||
{
|
||||
/* Nb of 16-bit data to program can be decreased */
|
||||
pFlash.DataRemaining--;
|
||||
|
||||
/* Check if there are still 16-bit data to program */
|
||||
if(pFlash.DataRemaining != 0)
|
||||
{
|
||||
/* Increment address to 16-bit */
|
||||
pFlash.Address += 2;
|
||||
addresstmp = pFlash.Address;
|
||||
|
||||
/* Shift to have next 16-bit data */
|
||||
pFlash.Data = (pFlash.Data >> 16);
|
||||
|
||||
/* Operation is completed, disable the PG Bit */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
|
||||
/*Program halfword (16-bit) at a specified address.*/
|
||||
FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Program ended. Return the selected address*/
|
||||
/* FLASH EOP interrupt user callback */
|
||||
if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
||||
}
|
||||
else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address - 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address - 6);
|
||||
}
|
||||
|
||||
/* Reset Address and stop Program procedure*/
|
||||
pFlash.Address = 0xFFFFFFFF;
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/* Check FLASH End of Operation flag */
|
||||
if(__HAL_FLASH_GET_FLAG( FLASH_FLAG_EOP_BANK2))
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
|
||||
|
||||
/* Process can continue only if no error detected */
|
||||
if(pFlash.ProcedureOnGoing != FLASH_PROC_NONE)
|
||||
{
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_PAGEERASE)
|
||||
{
|
||||
/* Nb of pages to erased can be decreased */
|
||||
pFlash.DataRemaining--;
|
||||
|
||||
/* Check if there are still pages to erase*/
|
||||
if(pFlash.DataRemaining != 0)
|
||||
{
|
||||
/* Indicate user which page address has been erased*/
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
||||
|
||||
/* Increment page address to next page */
|
||||
pFlash.Address += FLASH_PAGE_SIZE;
|
||||
addresstmp = pFlash.Address;
|
||||
|
||||
/* Operation is completed, disable the PER Bit */
|
||||
CLEAR_BIT(FLASH->CR2, FLASH_CR2_PER);
|
||||
|
||||
FLASH_PageErase(addresstmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*No more pages to Erase*/
|
||||
|
||||
/*Reset Address and stop Erase pages procedure*/
|
||||
pFlash.Address = 0xFFFFFFFF;
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
||||
}
|
||||
}
|
||||
else if(pFlash.ProcedureOnGoing == FLASH_PROC_MASSERASE)
|
||||
{
|
||||
/* Operation is completed, disable the MER Bit */
|
||||
CLEAR_BIT(FLASH->CR2, FLASH_CR2_MER);
|
||||
|
||||
if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_MER))
|
||||
{
|
||||
/* MassErase ended. Return the selected bank*/
|
||||
/* FLASH EOP interrupt user callback */
|
||||
HAL_FLASH_EndOfOperationCallback(0);
|
||||
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Nb of 16-bit data to program can be decreased */
|
||||
pFlash.DataRemaining--;
|
||||
|
||||
/* Check if there are still 16-bit data to program */
|
||||
if(pFlash.DataRemaining != 0)
|
||||
{
|
||||
/* Increment address to 16-bit */
|
||||
pFlash.Address += 2;
|
||||
addresstmp = pFlash.Address;
|
||||
|
||||
/* Shift to have next 16-bit data */
|
||||
pFlash.Data = (pFlash.Data >> 16);
|
||||
|
||||
/* Operation is completed, disable the PG Bit */
|
||||
CLEAR_BIT(FLASH->CR2, FLASH_CR2_PG);
|
||||
|
||||
/*Program halfword (16-bit) at a specified address.*/
|
||||
FLASH_Program_HalfWord(addresstmp, (uint16_t)pFlash.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*Program ended. Return the selected address*/
|
||||
/* FLASH EOP interrupt user callback */
|
||||
if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMHALFWORD)
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address);
|
||||
}
|
||||
else if (pFlash.ProcedureOnGoing == FLASH_PROC_PROGRAMWORD)
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address-2);
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL_FLASH_EndOfOperationCallback(pFlash.Address-6);
|
||||
}
|
||||
|
||||
/* Reset Address and stop Program procedure*/
|
||||
pFlash.Address = 0xFFFFFFFF;
|
||||
pFlash.ProcedureOnGoing = FLASH_PROC_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(pFlash.ProcedureOnGoing == FLASH_PROC_NONE)
|
||||
{
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/* Operation is completed, disable the PG, PER and MER Bits for both bank */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
|
||||
CLEAR_BIT(FLASH->CR2, (FLASH_CR2_PG | FLASH_CR2_PER | FLASH_CR2_MER));
|
||||
|
||||
/* Disable End of FLASH Operation and Error source interrupts for both banks */
|
||||
__HAL_FLASH_DISABLE_IT(FLASH_IT_EOP_BANK1 | FLASH_IT_ERR_BANK1 | FLASH_IT_EOP_BANK2 | FLASH_IT_ERR_BANK2);
|
||||
#else
|
||||
/* Operation is completed, disable the PG, PER and MER Bits */
|
||||
CLEAR_BIT(FLASH->CR, (FLASH_CR_PG | FLASH_CR_PER | FLASH_CR_MER));
|
||||
|
||||
/* Disable End of FLASH Operation and Error source interrupts */
|
||||
__HAL_FLASH_DISABLE_IT(FLASH_IT_EOP | FLASH_IT_ERR);
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
/* 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: No return value expected
|
||||
* - Pages Erase: Address of the page which has been erased
|
||||
* (if 0xFFFFFFFF, it means that all the selected pages have 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: No return value expected
|
||||
* - Pages Erase: Address of the page 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
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief management functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the FLASH
|
||||
memory operations.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH control register access
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Unlock(void)
|
||||
{
|
||||
if (HAL_IS_BIT_SET(FLASH->CR, FLASH_CR_LOCK))
|
||||
{
|
||||
/* Authorize the FLASH Registers access */
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
|
||||
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if (HAL_IS_BIT_SET(FLASH->CR2, FLASH_CR2_LOCK))
|
||||
{
|
||||
/* Authorize the FLASH BANK2 Registers access */
|
||||
WRITE_REG(FLASH->KEYR2, FLASH_KEY1);
|
||||
WRITE_REG(FLASH->KEYR2, FLASH_KEY2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
#endif /* FLASH_BANK2_END */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locks the FLASH control register access
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_Lock(void)
|
||||
{
|
||||
/* Set the LOCK Bit to lock the FLASH Registers access */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/* Set the LOCK Bit to lock the FLASH BANK2 Registers access */
|
||||
SET_BIT(FLASH->CR2, FLASH_CR2_LOCK);
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unlock the FLASH Option Control Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Unlock(void)
|
||||
{
|
||||
if (HAL_IS_BIT_CLR(FLASH->CR, FLASH_CR_OPTWRE))
|
||||
{
|
||||
/* Authorizes the Option Byte register programming */
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1);
|
||||
WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the FLASH Option Control Registers access.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Lock(void)
|
||||
{
|
||||
/* Clear the OPTWRE Bit to lock the FLASH Option Byte Registers access */
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_OPTWRE);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Launch the option byte loading.
|
||||
* @note This function will reset automatically the MCU.
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_FLASH_OB_Launch(void)
|
||||
{
|
||||
/* Initiates a system reset request to launch the option byte loading */
|
||||
HAL_NVIC_SystemReset();
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup FLASH_Exported_Functions_Group3 Peripheral State functions
|
||||
* @brief Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection permit to get in run-time the status of the FLASH peripheral.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get the specific FLASH error flag.
|
||||
* @retval FLASH_ErrorCode: The returned value can be:
|
||||
* @ref FLASH_Error_Codes
|
||||
*/
|
||||
uint32_t HAL_FLASH_GetError(void)
|
||||
{
|
||||
return pFlash.ErrorCode;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup FLASH_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Program a half-word (16-bit) at a specified address.
|
||||
* @param Address: specifies the address to be programmed.
|
||||
* @param Data: specifies the data to be programmed.
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_Program_HalfWord(uint32_t Address, uint16_t Data)
|
||||
{
|
||||
/* Clean the error context */
|
||||
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(Address <= FLASH_BANK1_END)
|
||||
{
|
||||
#endif /* FLASH_BANK2_END */
|
||||
/* Proceed to program the new data */
|
||||
SET_BIT(FLASH->CR, FLASH_CR_PG);
|
||||
#if defined(FLASH_BANK2_END)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Proceed to program the new data */
|
||||
SET_BIT(FLASH->CR2, FLASH_CR2_PG);
|
||||
}
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
/* Write data in the address */
|
||||
*(__IO uint16_t*)Address = Data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 tickstart = HAL_GetTick();
|
||||
|
||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY))
|
||||
{
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check FLASH End of Operation flag */
|
||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP))
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP);
|
||||
}
|
||||
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) ||
|
||||
__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR) ||
|
||||
__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
|
||||
{
|
||||
/*Save the error code*/
|
||||
FLASH_SetErrorCode();
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* If there is no error flag set */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
#if defined(FLASH_BANK2_END)
|
||||
/**
|
||||
* @brief Wait for a FLASH BANK2 operation to complete.
|
||||
* @param Timeout: maximum flash operation timeout
|
||||
* @retval HAL_StatusTypeDef HAL Status
|
||||
*/
|
||||
HAL_StatusTypeDef FLASH_WaitForLastOperationBank2(uint32_t Timeout)
|
||||
{
|
||||
/* Wait for the FLASH BANK2 operation to complete by polling on BUSY flag to be reset.
|
||||
Even if the FLASH BANK2 operation fails, the BUSY flag will be reset and an error
|
||||
flag will be set */
|
||||
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
|
||||
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY_BANK2))
|
||||
{
|
||||
if (Timeout != HAL_MAX_DELAY)
|
||||
{
|
||||
if((Timeout == 0) || ((HAL_GetTick()-tickstart) > Timeout))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check FLASH End of Operation flag */
|
||||
if (__HAL_FLASH_GET_FLAG(FLASH_FLAG_EOP_BANK2))
|
||||
{
|
||||
/* Clear FLASH End of Operation pending bit */
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP_BANK2);
|
||||
}
|
||||
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
|
||||
{
|
||||
/*Save the error code*/
|
||||
FLASH_SetErrorCode();
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* If there is an error flag set */
|
||||
return HAL_OK;
|
||||
|
||||
}
|
||||
#endif /* FLASH_BANK2_END */
|
||||
|
||||
/**
|
||||
* @brief Set the specific FLASH error flag.
|
||||
* @retval None
|
||||
*/
|
||||
static void FLASH_SetErrorCode(void)
|
||||
{
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR_BANK2))
|
||||
#else
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_WRPERR))
|
||||
#endif /* FLASH_BANK2_END */
|
||||
{
|
||||
pFlash.ErrorCode |= HAL_FLASH_ERROR_WRP;
|
||||
}
|
||||
#if defined(FLASH_BANK2_END)
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR) || __HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR_BANK2))
|
||||
#else
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_PGERR))
|
||||
#endif /* FLASH_BANK2_END */
|
||||
{
|
||||
pFlash.ErrorCode |= HAL_FLASH_ERROR_PROG;
|
||||
}
|
||||
|
||||
if(__HAL_FLASH_GET_FLAG(FLASH_FLAG_OPTVERR))
|
||||
{
|
||||
pFlash.ErrorCode |= HAL_FLASH_ERROR_OPTV;
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
|
||||
}
|
||||
|
||||
/* Clear FLASH error pending bits */
|
||||
#if defined(FLASH_BANK2_END)
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_WRPERR_BANK2 | FLASH_FLAG_PGERR | FLASH_FLAG_PGERR_BANK2);
|
||||
#else
|
||||
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR);
|
||||
#endif /* FLASH_BANK2_END */
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
1140
system/src/stm32f1xx/stm32f1xx_hal_flash_ex.c
Normal file
1140
system/src/stm32f1xx/stm32f1xx_hal_flash_ex.c
Normal file
File diff suppressed because it is too large
Load Diff
597
system/src/stm32f1xx/stm32f1xx_hal_gpio.c
Normal file
597
system/src/stm32f1xx/stm32f1xx_hal_gpio.c
Normal file
@ -0,0 +1,597 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_gpio.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @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 #####
|
||||
==============================================================================
|
||||
[..]
|
||||
Subject to the specific hardware characteristics of each I/O port listed in the datasheet, each
|
||||
port bit of the General Purpose IO (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.
|
||||
|
||||
[..]
|
||||
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 20 edge detectors in connectivity
|
||||
line devices, or 19 edge detectors in other devices for generating event/interrupt requests.
|
||||
Each input line can be independently configured to select the type (event or interrupt) and
|
||||
the corresponding trigger event (rising or falling or both). Each line can also masked
|
||||
independently. A pending register maintains the status line of the interrupt requests
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..]
|
||||
(#) Enable the GPIO APB2 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
|
||||
(++) 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
|
||||
(PC14 and PC15, respectively) 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 PD0 and PD1, respectively, when the HSE oscillator is off.
|
||||
The HSE has priority over the GPIO function.
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO GPIO
|
||||
* @brief GPIO HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup GPIO_Private_Constants GPIO Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define GPIO_MODE ((uint32_t)0x00000003)
|
||||
#define EXTI_MODE ((uint32_t)0x10000000)
|
||||
#define GPIO_MODE_IT ((uint32_t)0x00010000)
|
||||
#define GPIO_MODE_EVT ((uint32_t)0x00020000)
|
||||
#define RISING_EDGE ((uint32_t)0x00100000)
|
||||
#define FALLING_EDGE ((uint32_t)0x00200000)
|
||||
#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010)
|
||||
#define GPIO_NUMBER ((uint32_t)16)
|
||||
|
||||
/* Definitions for bit manipulation of CRL and CRH register */
|
||||
#define GPIO_CR_MODE_INPUT ((uint32_t)0x00000000) /*!< 00: Input mode (reset state) */
|
||||
#define GPIO_CR_CNF_ANALOG ((uint32_t)0x00000000) /*!< 00: Analog mode */
|
||||
#define GPIO_CR_CNF_INPUT_FLOATING ((uint32_t)0x00000004) /*!< 01: Floating input (reset state) */
|
||||
#define GPIO_CR_CNF_INPUT_PU_PD ((uint32_t)0x00000008) /*!< 10: Input with pull-up / pull-down */
|
||||
#define GPIO_CR_CNF_GP_OUTPUT_PP ((uint32_t)0x00000000) /*!< 00: General purpose output push-pull */
|
||||
#define GPIO_CR_CNF_GP_OUTPUT_OD ((uint32_t)0x00000004) /*!< 01: General purpose output Open-drain */
|
||||
#define GPIO_CR_CNF_AF_OUTPUT_PP ((uint32_t)0x00000008) /*!< 10: Alternate function output Push-pull */
|
||||
#define GPIO_CR_CNF_AF_OUTPUT_OD ((uint32_t)0x0000000C) /*!< 11: Alternate function output Open-drain */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions_Group1 Initialization and deinitialization functions
|
||||
* @brief Initialization and Configuration functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and deinitialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This section provides functions allowing to initialize and de-initialize the GPIOs
|
||||
to be ready for use.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
|
||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||
* @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;
|
||||
uint32_t ioposition = 0x00;
|
||||
uint32_t iocurrent = 0x00;
|
||||
uint32_t temp = 0x00;
|
||||
uint32_t config = 0x00;
|
||||
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
||||
uint32_t registeroffset = 0; /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
|
||||
|
||||
/* 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));
|
||||
|
||||
/* Configure the port pins */
|
||||
for (position = 0; position < GPIO_NUMBER; position++)
|
||||
{
|
||||
/* Get the IO position */
|
||||
ioposition = ((uint32_t)0x01) << position;
|
||||
|
||||
/* Get the current IO position */
|
||||
iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
|
||||
|
||||
if (iocurrent == ioposition)
|
||||
{
|
||||
/* Check the Alternate function parameters */
|
||||
assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
|
||||
|
||||
/* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
|
||||
switch (GPIO_Init->Mode)
|
||||
{
|
||||
/* If we are configuring the pin in OUTPUT push-pull mode */
|
||||
case GPIO_MODE_OUTPUT_PP:
|
||||
/* Check the GPIO speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
|
||||
break;
|
||||
|
||||
/* If we are configuring the pin in OUTPUT open-drain mode */
|
||||
case GPIO_MODE_OUTPUT_OD:
|
||||
/* Check the GPIO speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
|
||||
break;
|
||||
|
||||
/* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
|
||||
case GPIO_MODE_AF_PP:
|
||||
/* Check the GPIO speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
|
||||
break;
|
||||
|
||||
/* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
|
||||
case GPIO_MODE_AF_OD:
|
||||
/* Check the GPIO speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
|
||||
break;
|
||||
|
||||
/* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
|
||||
case GPIO_MODE_INPUT:
|
||||
case GPIO_MODE_IT_RISING:
|
||||
case GPIO_MODE_IT_FALLING:
|
||||
case GPIO_MODE_IT_RISING_FALLING:
|
||||
case GPIO_MODE_EVT_RISING:
|
||||
case GPIO_MODE_EVT_FALLING:
|
||||
case GPIO_MODE_EVT_RISING_FALLING:
|
||||
/* Check the GPIO pull parameter */
|
||||
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||
if(GPIO_Init->Pull == GPIO_NOPULL)
|
||||
{
|
||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
|
||||
}
|
||||
else if(GPIO_Init->Pull == GPIO_PULLUP)
|
||||
{
|
||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
||||
|
||||
/* Set the corresponding ODR bit */
|
||||
GPIOx->BSRR = ioposition;
|
||||
}
|
||||
else /* GPIO_PULLDOWN */
|
||||
{
|
||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
|
||||
|
||||
/* Reset the corresponding ODR bit */
|
||||
GPIOx->BRR = ioposition;
|
||||
}
|
||||
break;
|
||||
|
||||
/* If we are configuring the pin in INPUT analog mode */
|
||||
case GPIO_MODE_ANALOG:
|
||||
config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
|
||||
break;
|
||||
|
||||
/* Parameters are checked with assert_param */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if the current bit belongs to first half or last half of the pin count number
|
||||
in order to address CRH or CRL register*/
|
||||
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
||||
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2) : ((position - 8) << 2);
|
||||
|
||||
/* Apply the new configuration of the pin to the register */
|
||||
MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), (config << registeroffset));
|
||||
|
||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||
/* Configure the External Interrupt or event for the current IO */
|
||||
if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
||||
{
|
||||
/* Enable AFIO Clock */
|
||||
__HAL_RCC_AFIO_CLK_ENABLE();
|
||||
temp = AFIO->EXTICR[position >> 2];
|
||||
CLEAR_BIT(temp, ((uint32_t)0x0F) << (4 * (position & 0x03)));
|
||||
SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4 * (position & 0x03)));
|
||||
AFIO->EXTICR[position >> 2] = temp;
|
||||
|
||||
|
||||
/* Configure the interrupt mask */
|
||||
if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
||||
{
|
||||
SET_BIT(EXTI->IMR, iocurrent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(EXTI->IMR, iocurrent);
|
||||
}
|
||||
|
||||
/* Configure the event mask */
|
||||
if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
||||
{
|
||||
SET_BIT(EXTI->EMR, iocurrent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(EXTI->EMR, iocurrent);
|
||||
}
|
||||
|
||||
/* Enable or disable the rising trigger */
|
||||
if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
||||
{
|
||||
SET_BIT(EXTI->RTSR, iocurrent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(EXTI->RTSR, iocurrent);
|
||||
}
|
||||
|
||||
/* Enable or disable the falling trigger */
|
||||
if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
||||
{
|
||||
SET_BIT(EXTI->FTSR, iocurrent);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLEAR_BIT(EXTI->FTSR, iocurrent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief De-initializes the GPIOx peripheral registers to their default reset values.
|
||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||
* @param GPIO_Pin: specifies the port bit to be written.
|
||||
* This parameter can be one 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 = 0x00;
|
||||
uint32_t iocurrent = 0x00;
|
||||
uint32_t tmp = 0x00;
|
||||
__IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
|
||||
uint32_t registeroffset = 0;
|
||||
|
||||
/* 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) != 0)
|
||||
{
|
||||
/* Get current io position */
|
||||
iocurrent = (GPIO_Pin) & ((uint32_t)1 << position);
|
||||
|
||||
if (iocurrent)
|
||||
{
|
||||
/*------------------------- GPIO Mode Configuration --------------------*/
|
||||
/* Check if the current bit belongs to first half or last half of the pin count number
|
||||
in order to address CRH or CRL register */
|
||||
configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL : &GPIOx->CRH;
|
||||
registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2) : ((position - 8) << 2);
|
||||
|
||||
/* CRL/CRH default value is floating input(0x04) shifted to correct position */
|
||||
MODIFY_REG(*configregister, ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset ), GPIO_CRL_CNF0_0 << registeroffset);
|
||||
|
||||
/* ODR default value is 0 */
|
||||
CLEAR_BIT(GPIOx->ODR, iocurrent);
|
||||
|
||||
/*------------------------- EXTI Mode Configuration --------------------*/
|
||||
/* Clear the External Interrupt or Event for the current IO */
|
||||
|
||||
tmp = AFIO->EXTICR[position >> 2];
|
||||
tmp &= (((uint32_t)0x0F) << (4 * (position & 0x03)));
|
||||
if(tmp == (GPIO_GET_INDEX(GPIOx) << (4 * (position & 0x03))))
|
||||
{
|
||||
tmp = ((uint32_t)0x0F) << (4 * (position & 0x03));
|
||||
CLEAR_BIT(AFIO->EXTICR[position >> 2], tmp);
|
||||
|
||||
/* Clear EXTI line configuration */
|
||||
CLEAR_BIT(EXTI->IMR, (uint32_t)iocurrent);
|
||||
CLEAR_BIT(EXTI->EMR, (uint32_t)iocurrent);
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
CLEAR_BIT(EXTI->RTSR, (uint32_t)iocurrent);
|
||||
CLEAR_BIT(EXTI->FTSR, (uint32_t)iocurrent);
|
||||
}
|
||||
}
|
||||
|
||||
position++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
|
||||
* @brief GPIO Read and Write
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### IO operation functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to manage the GPIOs.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Reads the specified input port pin.
|
||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||
* @param GPIO_Pin: specifies the port bit to read.
|
||||
* This parameter can be 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) != (uint32_t)GPIO_PIN_RESET)
|
||||
{
|
||||
bitstatus = GPIO_PIN_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitstatus = GPIO_PIN_RESET;
|
||||
}
|
||||
return bitstatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets or clears the selected data port bit.
|
||||
*
|
||||
* @note This function uses GPIOx_BSRR register 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..G depending on device used) to select the GPIO peripheral
|
||||
* @param GPIO_Pin: specifies the port bit to be written.
|
||||
* This parameter can be one 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_BIT_RESET: to clear the port pin
|
||||
* @arg GPIO_BIT_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 = GPIO_Pin;
|
||||
}
|
||||
else
|
||||
{
|
||||
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Toggles the specified GPIO pin
|
||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||
* @param GPIO_Pin: Specifies the pins to be toggled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Pin));
|
||||
|
||||
GPIOx->ODR ^= GPIO_Pin;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Locks GPIO Pins configuration registers.
|
||||
* @note The locking mechanism allows the IO configuration to be frozen. When the LOCK sequence
|
||||
* has been applied on a port bit, it is no longer possible to modify the value of the port bit until
|
||||
* the next reset.
|
||||
* @param GPIOx: where x can be (A..G depending on device used) to select the GPIO peripheral
|
||||
* @param GPIO_Pin: specifies the port bit 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 */
|
||||
SET_BIT(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 bit*/
|
||||
tmp = GPIOx->LCKR;
|
||||
|
||||
if((uint32_t)(GPIOx->LCKR & GPIO_LCKR_LCKK))
|
||||
{
|
||||
return HAL_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles EXTI interrupt request.
|
||||
* @param GPIO_Pin: Specifies the pins connected 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) != RESET)
|
||||
{
|
||||
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
|
||||
HAL_GPIO_EXTI_Callback(GPIO_Pin);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief EXTI line detection callback
|
||||
* @param GPIO_Pin: Specifies the pins connected EXTI line
|
||||
* @retval None
|
||||
*/
|
||||
__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
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
145
system/src/stm32f1xx/stm32f1xx_hal_gpio_ex.c
Normal file
145
system/src/stm32f1xx/stm32f1xx_hal_gpio_ex.c
Normal file
@ -0,0 +1,145 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_gpio_ex.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief GPIO Extension HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the General Purpose Input/Output (GPIO) extension peripheral.
|
||||
* + Extended features functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### GPIO Peripheral extension features #####
|
||||
==============================================================================
|
||||
[..] GPIO module on STM32F1 family, manage also the AFIO register:
|
||||
(+) Possibility to use the EVENTOUT Cortex feature
|
||||
|
||||
##### How to use this driver #####
|
||||
==============================================================================
|
||||
[..] This driver provides functions to use EVENTOUT Cortex feature
|
||||
(#) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
|
||||
(#) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
|
||||
(#) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIOEx GPIOEx
|
||||
* @brief GPIO HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
|
||||
/** @defgroup GPIOEx_Exported_Functions GPIOEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup GPIOEx_Exported_Functions_Group1 Extended features functions
|
||||
* @brief Extended features functions
|
||||
*
|
||||
@verbatim
|
||||
==============================================================================
|
||||
##### Extended features functions #####
|
||||
==============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Configure EVENTOUT Cortex feature using the function HAL_GPIOEx_ConfigEventout()
|
||||
(+) Activate EVENTOUT Cortex feature using the HAL_GPIOEx_EnableEventout()
|
||||
(+) Deactivate EVENTOUT Cortex feature using the HAL_GPIOEx_DisableEventout()
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures the port and pin on which the EVENTOUT Cortex signal will be connected.
|
||||
* @param GPIO_PortSource Select the port used to output the Cortex EVENTOUT signal.
|
||||
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PORT.
|
||||
* @param GPIO_PinSource Select the pin used to output the Cortex EVENTOUT signal.
|
||||
* This parameter can be a value of @ref GPIOEx_EVENTOUT_PIN.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIOEx_ConfigEventout(uint32_t GPIO_PortSource, uint32_t GPIO_PinSource)
|
||||
{
|
||||
/* Verify the parameters */
|
||||
assert_param(IS_AFIO_EVENTOUT_PORT(GPIO_PortSource));
|
||||
assert_param(IS_AFIO_EVENTOUT_PIN(GPIO_PinSource));
|
||||
|
||||
/* Apply the new configuration */
|
||||
MODIFY_REG(AFIO->EVCR, (AFIO_EVCR_PORT)|(AFIO_EVCR_PIN), (GPIO_PortSource)|(GPIO_PinSource));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the Event Output.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIOEx_EnableEventout(void)
|
||||
{
|
||||
SET_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the Event Output.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIOEx_DisableEventout(void)
|
||||
{
|
||||
CLEAR_BIT(AFIO->EVCR, AFIO_EVCR_EVOE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
636
system/src/stm32f1xx/stm32f1xx_hal_pwr.c
Normal file
636
system/src/stm32f1xx/stm32f1xx_hal_pwr.c
Normal file
@ -0,0 +1,636 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_pwr.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief PWR HAL module driver.
|
||||
*
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Power Controller (PWR) peripheral:
|
||||
* + Initialization/de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWR PWR
|
||||
* @brief PWR HAL module driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
|
||||
/** @defgroup PWR_Private_Constants PWR Private Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWR_PVD_Mode_Mask PWR PVD Mode Mask
|
||||
* @{
|
||||
*/
|
||||
#define PVD_MODE_IT ((uint32_t)0x00010000)
|
||||
#define PVD_MODE_EVT ((uint32_t)0x00020000)
|
||||
#define PVD_RISING_EDGE ((uint32_t)0x00000001)
|
||||
#define PVD_FALLING_EDGE ((uint32_t)0x00000002)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup PWR_register_alias_address PWR Register alias address
|
||||
* @{
|
||||
*/
|
||||
/* ------------- PWR registers bit address in the alias region ---------------*/
|
||||
#define PWR_OFFSET (PWR_BASE - PERIPH_BASE)
|
||||
#define PWR_CR_OFFSET 0x00
|
||||
#define PWR_CSR_OFFSET 0x04
|
||||
#define PWR_CR_OFFSET_BB (PWR_OFFSET + PWR_CR_OFFSET)
|
||||
#define PWR_CSR_OFFSET_BB (PWR_OFFSET + PWR_CSR_OFFSET)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PWR_CR_register_alias PWR CR Register alias address
|
||||
* @{
|
||||
*/
|
||||
/* --- CR Register ---*/
|
||||
/* Alias word address of LPSDSR bit */
|
||||
#define LPSDSR_BIT_NUMBER POSITION_VAL(PWR_CR_LPDS)
|
||||
#define CR_LPSDSR_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (LPSDSR_BIT_NUMBER * 4)))
|
||||
|
||||
/* Alias word address of DBP bit */
|
||||
#define DBP_BIT_NUMBER POSITION_VAL(PWR_CR_DBP)
|
||||
#define CR_DBP_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (DBP_BIT_NUMBER * 4)))
|
||||
|
||||
/* Alias word address of PVDE bit */
|
||||
#define PVDE_BIT_NUMBER POSITION_VAL(PWR_CR_PVDE)
|
||||
#define CR_PVDE_BB ((uint32_t)(PERIPH_BB_BASE + (PWR_CR_OFFSET_BB * 32) + (PVDE_BIT_NUMBER * 4)))
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup PWR_CSR_register_alias PWR CSR Register alias address
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* --- CSR Register ---*/
|
||||
/* Alias word address of EWUP1 bit */
|
||||
#define CSR_EWUP_BB(VAL) ((uint32_t)(PERIPH_BB_BASE + (PWR_CSR_OFFSET_BB * 32) + (POSITION_VAL(VAL) * 4)))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/** @defgroup PWR_Private_Functions PWR Private Functions
|
||||
* brief WFE cortex command overloaded for HAL_PWR_EnterSTOPMode usage only (see Workaround section)
|
||||
* @{
|
||||
*/
|
||||
static void PWR_OverloadWfe(void);
|
||||
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
__NOINLINE
|
||||
static void PWR_OverloadWfe(void)
|
||||
{
|
||||
__asm volatile( "wfe" );
|
||||
__asm volatile( "nop" );
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/** @defgroup PWR_Exported_Functions PWR Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup PWR_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and de-initialization functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
After reset, the backup domain (RTC registers, RTC backup data
|
||||
registers) is protected against possible unwanted
|
||||
write accesses.
|
||||
To enable access to the RTC Domain and RTC registers, proceed as follows:
|
||||
(+) Enable the Power Controller (PWR) APB1 interface clock using the
|
||||
__HAL_RCC_PWR_CLK_ENABLE() macro.
|
||||
(+) Enable access to RTC domain using the HAL_PWR_EnableBkUpAccess() function.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Deinitializes the 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables access to the backup domain (RTC registers, RTC
|
||||
* backup data registers ).
|
||||
* @note If the HSE divided by 128 is used as the RTC clock, the
|
||||
* Backup Domain Access should be kept enabled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableBkUpAccess(void)
|
||||
{
|
||||
/* Enable access to RTC and backup registers */
|
||||
*(__IO uint32_t *) CR_DBP_BB = (uint32_t)ENABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables access to the backup domain (RTC registers, RTC
|
||||
* backup data registers).
|
||||
* @note If the HSE divided by 128 is used as the RTC clock, the
|
||||
* Backup Domain Access should be kept enabled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableBkUpAccess(void)
|
||||
{
|
||||
/* Disable access to RTC and backup registers */
|
||||
*(__IO uint32_t *) CR_DBP_BB = (uint32_t)DISABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup 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 (PLS[2:0] bits in the PWR_CR).
|
||||
|
||||
(+) A 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
|
||||
line16 and can generate an interrupt if enabled. This is done through
|
||||
__HAL_PVD_EXTI_ENABLE_IT() macro.
|
||||
(+) The PVD is stopped in Standby mode.
|
||||
|
||||
*** WakeUp pin configuration ***
|
||||
================================
|
||||
[..]
|
||||
(+) WakeUp pin is used to wake up the system from Standby mode. This pin is
|
||||
forced in input pull-down configuration and is active on rising edges.
|
||||
(+) There is one WakeUp pin:
|
||||
WakeUp Pin 1 on PA.00.
|
||||
|
||||
[..]
|
||||
|
||||
*** Low Power modes configuration ***
|
||||
=====================================
|
||||
[..]
|
||||
The device features 3 low-power modes:
|
||||
(+) Sleep mode: CPU clock off, all peripherals including Cortex-M3 core peripherals like
|
||||
NVIC, SysTick, etc. are kept running
|
||||
(+) Stop mode: All clocks are stopped
|
||||
(+) Standby mode: 1.8V domain powered off
|
||||
|
||||
|
||||
*** Sleep mode ***
|
||||
==================
|
||||
[..]
|
||||
(+) Entry:
|
||||
The Sleep mode is entered by using the HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFx)
|
||||
functions with
|
||||
(++) PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
||||
(++) PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
||||
|
||||
(+) Exit:
|
||||
(++) WFI entry mode, Any peripheral interrupt acknowledged by the nested vectored interrupt
|
||||
controller (NVIC) can wake up the device from Sleep mode.
|
||||
(++) WFE entry mode, Any wakeup event can wake up the device from Sleep mode.
|
||||
(+++) Any peripheral interrupt w/o NVIC configuration & SEVONPEND bit set in the Cortex (HAL_PWR_EnableSEVOnPend)
|
||||
(+++) Any EXTI Line (Internal or External) configured in Event mode
|
||||
|
||||
*** Stop mode ***
|
||||
=================
|
||||
[..]
|
||||
The Stop mode is based on the Cortex-M3 deepsleep mode combined with peripheral
|
||||
clock gating. The voltage regulator can be configured either in normal or low-power mode.
|
||||
In Stop mode, all clocks in the 1.8 V domain are stopped, the PLL, the HSI and the HSE RC
|
||||
oscillators are disabled. SRAM and register contents are preserved.
|
||||
In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||
|
||||
(+) Entry:
|
||||
The Stop mode is entered using the HAL_PWR_EnterSTOPMode(PWR_REGULATOR_VALUE, PWR_SLEEPENTRY_WFx )
|
||||
function with:
|
||||
(++) PWR_REGULATOR_VALUE= PWR_MAINREGULATOR_ON: Main regulator ON.
|
||||
(++) PWR_REGULATOR_VALUE= PWR_LOWPOWERREGULATOR_ON: Low Power regulator ON.
|
||||
(++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFI: enter STOP mode with WFI instruction
|
||||
(++) PWR_SLEEPENTRY_WFx= PWR_SLEEPENTRY_WFE: enter STOP mode with WFE instruction
|
||||
(+) Exit:
|
||||
(++) WFI entry mode, Any EXTI Line (Internal or External) configured in Interrupt mode with NVIC configured
|
||||
(++) WFE entry mode, Any EXTI Line (Internal or External) configured in Event mode.
|
||||
|
||||
*** Standby mode ***
|
||||
====================
|
||||
[..]
|
||||
The Standby mode allows to achieve the lowest power consumption. It is based on the
|
||||
Cortex-M3 deepsleep mode, with the voltage regulator disabled. The 1.8 V domain is
|
||||
consequently powered off. The PLL, the HSI oscillator and the HSE oscillator are also
|
||||
switched off. SRAM and register contents are lost except for registers in the Backup domain
|
||||
and Standby circuitry
|
||||
|
||||
(+) Entry:
|
||||
(++) The Standby mode is entered using the HAL_PWR_EnterSTANDBYMode() function.
|
||||
(+) Exit:
|
||||
(++) WKUP pin rising edge, RTC alarm event rising edge, external Reset in
|
||||
NRSTpin, IWDG Reset
|
||||
|
||||
*** Auto-wakeup (AWU) from low-power mode ***
|
||||
=============================================
|
||||
[..]
|
||||
|
||||
(+) The MCU can be woken up from low-power mode by an RTC Alarm event,
|
||||
without depending on an external interrupt (Auto-wakeup mode).
|
||||
|
||||
(+) RTC auto-wakeup (AWU) from the Stop and Standby modes
|
||||
|
||||
(++) To wake up from the Stop mode with an RTC alarm event, it is necessary to
|
||||
configure the RTC to generate the RTC alarm using the HAL_RTC_SetAlarm_IT() function.
|
||||
|
||||
*** PWR Workarounds linked to Silicon Limitation ***
|
||||
====================================================
|
||||
[..]
|
||||
Below the list of all silicon limitations known on STM32F1xx prouct.
|
||||
|
||||
(#)Workarounds Implemented inside PWR HAL Driver
|
||||
(##)Debugging Stop mode with WFE entry - overloaded the WFE by an internal function
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Configures the voltage threshold detected by the Power Voltage Detector(PVD).
|
||||
* @param sConfigPVD: pointer to an PWR_PVDTypeDef structure that contains the configuration
|
||||
* information for the PVD.
|
||||
* @note Refer to the electrical characteristics of your device datasheet for
|
||||
* more details about the voltage threshold corresponding to each
|
||||
* detection level.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_ConfigPVD(PWR_PVDTypeDef *sConfigPVD)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_PVD_LEVEL(sConfigPVD->PVDLevel));
|
||||
assert_param(IS_PWR_PVD_MODE(sConfigPVD->Mode));
|
||||
|
||||
/* Set PLS[7:5] bits according to PVDLevel value */
|
||||
MODIFY_REG(PWR->CR, PWR_CR_PLS, sConfigPVD->PVDLevel);
|
||||
|
||||
/* Clear any previous config. Keep it clear if no event or IT mode is selected */
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_EVENT();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_IT();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_FALLING_EDGE();
|
||||
__HAL_PWR_PVD_EXTI_DISABLE_RISING_EDGE();
|
||||
|
||||
/* Configure interrupt mode */
|
||||
if((sConfigPVD->Mode & PVD_MODE_IT) == PVD_MODE_IT)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_IT();
|
||||
}
|
||||
|
||||
/* Configure event mode */
|
||||
if((sConfigPVD->Mode & PVD_MODE_EVT) == PVD_MODE_EVT)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_EVENT();
|
||||
}
|
||||
|
||||
/* Configure the edge */
|
||||
if((sConfigPVD->Mode & PVD_RISING_EDGE) == PVD_RISING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_RISING_EDGE();
|
||||
}
|
||||
|
||||
if((sConfigPVD->Mode & PVD_FALLING_EDGE) == PVD_FALLING_EDGE)
|
||||
{
|
||||
__HAL_PWR_PVD_EXTI_ENABLE_FALLING_EDGE();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the Power Voltage Detector(PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnablePVD(void)
|
||||
{
|
||||
/* Enable the power voltage detector */
|
||||
*(__IO uint32_t *) CR_PVDE_BB = (uint32_t)ENABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the Power Voltage Detector(PVD).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisablePVD(void)
|
||||
{
|
||||
/* Disable the power voltage detector */
|
||||
*(__IO uint32_t *) CR_PVDE_BB = (uint32_t)DISABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables the WakeUp PINx functionality.
|
||||
* @param WakeUpPinx: Specifies the Power Wake-Up pin to enable.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg PWR_WAKEUP_PIN1
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnableWakeUpPin(uint32_t WakeUpPinx)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
||||
/* Enable the EWUPx pin */
|
||||
*(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)ENABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables the WakeUp PINx functionality.
|
||||
* @param WakeUpPinx: Specifies the Power Wake-Up pin to disable.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg PWR_WAKEUP_PIN1
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_DisableWakeUpPin(uint32_t WakeUpPinx)
|
||||
{
|
||||
/* Check the parameter */
|
||||
assert_param(IS_PWR_WAKEUP_PIN(WakeUpPinx));
|
||||
/* Disable the EWUPx pin */
|
||||
*(__IO uint32_t *) CSR_EWUP_BB(WakeUpPinx) = (uint32_t)DISABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters Sleep mode.
|
||||
* @note In Sleep mode, all I/O pins keep the same state as in Run mode.
|
||||
* @param Regulator: Regulator state as no effect in SLEEP mode - allows to support portability from legacy software
|
||||
* @param SLEEPEntry: Specifies if SLEEP mode is entered with WFI or WFE instruction.
|
||||
* When WFI entry is used, tick interrupt have to be disabled if not desired as
|
||||
* the interrupt wake up source.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg PWR_SLEEPENTRY_WFI: enter SLEEP mode with WFI instruction
|
||||
* @arg PWR_SLEEPENTRY_WFE: enter SLEEP mode with WFE instruction
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
/* No check on Regulator because parameter not used in SLEEP mode */
|
||||
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 Enters Stop mode.
|
||||
* @note In Stop mode, all I/O pins keep the same state as in Run mode.
|
||||
* @note When exiting Stop mode by using an interrupt or a wakeup event,
|
||||
* HSI RC oscillator is selected as system clock.
|
||||
* @note When the voltage regulator operates in low power mode, an additional
|
||||
* startup delay is incurred when waking up from Stop mode.
|
||||
* By keeping the internal regulator ON during Stop mode, the consumption
|
||||
* is higher although the startup time is reduced.
|
||||
* @param Regulator: Specifies the regulator state in Stop mode.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg PWR_MAINREGULATOR_ON: Stop mode with regulator ON
|
||||
* @arg PWR_LOWPOWERREGULATOR_ON: Stop mode with low power regulator ON
|
||||
* @param STOPEntry: Specifies if Stop mode in entered with WFI or WFE instruction.
|
||||
* This parameter can be one of the following values:
|
||||
* @arg PWR_STOPENTRY_WFI: Enter Stop mode with WFI instruction
|
||||
* @arg PWR_STOPENTRY_WFE: Enter Stop mode with WFE instruction
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSTOPMode(uint32_t Regulator, uint8_t STOPEntry)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_PWR_REGULATOR(Regulator));
|
||||
assert_param(IS_PWR_STOP_ENTRY(STOPEntry));
|
||||
|
||||
/* Clear PDDS bit in PWR register to specify entering in STOP mode when CPU enter in Deepsleep */
|
||||
CLEAR_BIT(PWR->CR, PWR_CR_PDDS);
|
||||
|
||||
/* Select the voltage regulator mode by setting LPDS bit in PWR register according to Regulator parameter value */
|
||||
MODIFY_REG(PWR->CR, PWR_CR_LPDS, 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();
|
||||
PWR_OverloadWfe(); /* WFE redefine locally */
|
||||
PWR_OverloadWfe(); /* WFE redefine locally */
|
||||
}
|
||||
/* Reset SLEEPDEEP bit of Cortex System Control Register */
|
||||
CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enters Standby mode.
|
||||
* @note In Standby mode, all I/O pins are high impedance except for:
|
||||
* - Reset pad (still available)
|
||||
* - TAMPER pin if configured for tamper or calibration out.
|
||||
* - WKUP pin (PA0) if enabled.
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_EnterSTANDBYMode(void)
|
||||
{
|
||||
/* Select Standby mode */
|
||||
SET_BIT(PWR->CR, PWR_CR_PDDS);
|
||||
|
||||
/* Set SLEEPDEEP bit of Cortex System Control Register */
|
||||
SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
|
||||
|
||||
/* This option is used to ensure that store operations are completed */
|
||||
#if defined ( __CC_ARM)
|
||||
__force_stores();
|
||||
#endif
|
||||
/* Request Wait For Interrupt */
|
||||
__WFI();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Indicates Sleep-On-Exit when returning from Handler mode to Thread mode.
|
||||
* @note Set SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
||||
* re-enters SLEEP mode when an interruption handling is over.
|
||||
* 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 Disables Sleep-On-Exit feature when returning from Handler mode to Thread mode.
|
||||
* @note Clears SLEEPONEXIT bit of SCR register. When this bit is set, the processor
|
||||
* re-enters SLEEP 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 Enables CORTEX M3 SEVONPEND bit.
|
||||
* @note Sets SEVONPEND bit of SCR register. When this bit is set, this causes
|
||||
* WFE to wake up when an interrupt moves from inactive to pended.
|
||||
* @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 Disables CORTEX M3 SEVONPEND bit.
|
||||
* @note Clears SEVONPEND bit of SCR register. When this bit is set, this causes
|
||||
* WFE to wake up when an interrupt moves from inactive to pended.
|
||||
* @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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function handles the PWR PVD interrupt request.
|
||||
* @note This API should be called under the PVD_IRQHandler().
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_PWR_PVD_IRQHandler(void)
|
||||
{
|
||||
/* Check PWR exti flag */
|
||||
if(__HAL_PWR_PVD_EXTI_GET_FLAG() != RESET)
|
||||
{
|
||||
/* PWR PVD interrupt user callback */
|
||||
HAL_PWR_PVDCallback();
|
||||
|
||||
/* Clear PWR Exti pending bit */
|
||||
__HAL_PWR_PVD_EXTI_CLEAR_FLAG();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief PWR PVD interrupt callback
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_PWR_PVDCallback(void)
|
||||
{
|
||||
/* NOTE : This function Should not be modified, when the callback is needed,
|
||||
the HAL_PWR_PVDCallback could be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
1270
system/src/stm32f1xx/stm32f1xx_hal_rcc.c
Normal file
1270
system/src/stm32f1xx/stm32f1xx_hal_rcc.c
Normal file
File diff suppressed because it is too large
Load Diff
870
system/src/stm32f1xx/stm32f1xx_hal_rcc_ex.c
Normal file
870
system/src/stm32f1xx/stm32f1xx_hal_rcc_ex.c
Normal file
@ -0,0 +1,870 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_rcc_ex.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief Extended RCC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities RCC extension peripheral:
|
||||
* + Extended Peripheral Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/** @defgroup RCCEx RCCEx
|
||||
* @brief RCC Extension HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/** @defgroup RCCEx_Private_Constants RCCEx Private Constants
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/** @defgroup RCCEx_Private_Macros RCCEx Private Macros
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group1 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 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) are set to their reset values.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
|
||||
* RCC_PeriphCLKInitTypeDef.
|
||||
* @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
|
||||
* contains the configuration information for the Extended Peripherals clocks(RTC clock).
|
||||
*
|
||||
* @note Care must be taken when 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) are set to their reset values.
|
||||
*
|
||||
* @note In case of STM32F105xC or STM32F107xC devices, PLLI2S will be enabled if requested on
|
||||
* one of 2 I2S interfaces. When PLLI2S is enabled, you need to call HAL_RCCEx_DisablePLLI2S to
|
||||
* manually disable it.
|
||||
*
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
uint32_t tickstart = 0, temp_reg = 0;
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t pllactive = 0;
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
||||
|
||||
/*------------------------------- RTC/LCD Configuration ------------------------*/
|
||||
if ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC))
|
||||
{
|
||||
/* check for RTC Parameters used to output RTCCLK */
|
||||
assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
|
||||
|
||||
/* Enable Power Clock*/
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* Enable write access to Backup domain */
|
||||
SET_BIT(PWR->CR, PWR_CR_DBP);
|
||||
|
||||
/* Wait for Backup domain Write protection disable */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
while((PWR->CR & PWR_CR_DBP) == RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */
|
||||
temp_reg = (RCC->BDCR & RCC_BDCR_RTCSEL);
|
||||
if((temp_reg != 0x00000000U) && (temp_reg != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL)))
|
||||
{
|
||||
/* Store the content of BDCR register before the reset of Backup Domain */
|
||||
temp_reg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
|
||||
/* RTC Clock selection can be changed only if the Backup Domain is reset */
|
||||
__HAL_RCC_BACKUPRESET_FORCE();
|
||||
__HAL_RCC_BACKUPRESET_RELEASE();
|
||||
/* Restore the Content of BDCR register */
|
||||
RCC->BDCR = temp_reg;
|
||||
|
||||
/* Wait for LSERDY if LSE was enabled */
|
||||
if (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSEON))
|
||||
{
|
||||
/* Get timeout */
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till LSE is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
__HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
||||
}
|
||||
|
||||
/*------------------------------ ADC clock Configuration ------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_ADCPLLCLK_DIV(PeriphClkInit->AdcClockSelection));
|
||||
|
||||
/* Configure the ADC clock source */
|
||||
__HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
|
||||
}
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/*------------------------------ I2S2 Configuration ------------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S2) == RCC_PERIPHCLK_I2S2)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2S2CLKSOURCE(PeriphClkInit->I2s2ClockSelection));
|
||||
|
||||
/* Configure the I2S2 clock source */
|
||||
__HAL_RCC_I2S2_CONFIG(PeriphClkInit->I2s2ClockSelection);
|
||||
}
|
||||
|
||||
/*------------------------------ I2S3 Configuration ------------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S3) == RCC_PERIPHCLK_I2S3)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_I2S3CLKSOURCE(PeriphClkInit->I2s3ClockSelection));
|
||||
|
||||
/* Configure the I2S3 clock source */
|
||||
__HAL_RCC_I2S3_CONFIG(PeriphClkInit->I2s3ClockSelection);
|
||||
}
|
||||
|
||||
/*------------------------------ PLL I2S Configuration ----------------------*/
|
||||
/* Check that PLLI2S need to be enabled */
|
||||
if (HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S2SRC) || HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
|
||||
{
|
||||
/* Update flag to indicate that PLL I2S should be active */
|
||||
pllactive = 1;
|
||||
}
|
||||
|
||||
/* Check if PLL I2S need to be enabled */
|
||||
if (pllactive == 1)
|
||||
{
|
||||
/* Enable PLL I2S only if not active */
|
||||
if (HAL_IS_BIT_CLR(RCC->CR, RCC_CR_PLL3ON))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLLI2S_MUL(PeriphClkInit->PLLI2S.PLLI2SMUL));
|
||||
assert_param(IS_RCC_HSE_PREDIV2(PeriphClkInit->PLLI2S.HSEPrediv2Value));
|
||||
|
||||
/* Prediv2 can be written only when the PLL2 is disabled. */
|
||||
/* Return an error only if new value is different from the programmed value */
|
||||
if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
|
||||
(__HAL_RCC_HSE_GET_PREDIV2() != PeriphClkInit->PLLI2S.HSEPrediv2Value))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Configure the HSE prediv2 factor --------------------------------*/
|
||||
__HAL_RCC_HSE_PREDIV2_CONFIG(PeriphClkInit->PLLI2S.HSEPrediv2Value);
|
||||
|
||||
/* Configure the main PLLI2S multiplication factors. */
|
||||
__HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SMUL);
|
||||
|
||||
/* Enable the main PLLI2S. */
|
||||
__HAL_RCC_PLLI2S_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLI2S is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Return an error only if user wants to change the PLLI2SMUL whereas PLLI2S is active */
|
||||
if (READ_BIT(RCC->CFGR2, RCC_CFGR2_PLL3MUL) != PeriphClkInit->PLLI2S.PLLI2SMUL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|
||||
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|
||||
|| defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/*------------------------------ USB clock Configuration ------------------*/
|
||||
if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == RCC_PERIPHCLK_USB)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_USBPLLCLK_DIV(PeriphClkInit->UsbClockSelection));
|
||||
|
||||
/* Configure the USB clock source */
|
||||
__HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
|
||||
}
|
||||
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the PeriphClkInit 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(RTC, I2S, ADC clocks).
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
||||
{
|
||||
uint32_t srcclk = 0;
|
||||
|
||||
/* Set all possible values for the extended clock type parameter------------*/
|
||||
PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_RTC;
|
||||
|
||||
/* Get the RTC configuration -----------------------------------------------*/
|
||||
srcclk = __HAL_RCC_GET_RTC_SOURCE();
|
||||
/* Source clock is LSE or LSI*/
|
||||
PeriphClkInit->RTCClockSelection = srcclk;
|
||||
|
||||
/* Get the ADC clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_ADC;
|
||||
PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/* Get the I2S2 clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
|
||||
PeriphClkInit->I2s2ClockSelection = __HAL_RCC_GET_I2S2_SOURCE();
|
||||
|
||||
/* Get the I2S3 clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
|
||||
PeriphClkInit->I2s3ClockSelection = __HAL_RCC_GET_I2S3_SOURCE();
|
||||
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
#if defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* Get the I2S2 clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S2;
|
||||
PeriphClkInit->I2s2ClockSelection = RCC_I2S2CLKSOURCE_SYSCLK;
|
||||
|
||||
/* Get the I2S3 clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_I2S3;
|
||||
PeriphClkInit->I2s3ClockSelection = RCC_I2S3CLKSOURCE_SYSCLK;
|
||||
|
||||
#endif /* STM32F103xE || STM32F103xG */
|
||||
|
||||
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|
||||
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|
||||
|| defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/* Get the USB clock configuration -----------------------------------------*/
|
||||
PeriphClkInit->PeriphClockSelection |= RCC_PERIPHCLK_USB;
|
||||
PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
|
||||
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the peripheral clock frequency
|
||||
* @note Returns 0 if peripheral clock is unknown
|
||||
* @param PeriphClk Peripheral clock identifier
|
||||
* This parameter can be one of the following values:
|
||||
* @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
|
||||
@if STM32F103xE
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
@endif
|
||||
@if STM32F103xG
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
@endif
|
||||
@if STM32F105xC
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
|
||||
@endif
|
||||
@if STM32F107xC
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S3 I2S3 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_I2S2 I2S2 peripheral clock
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
|
||||
@endif
|
||||
@if STM32F102xx
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
|
||||
@endif
|
||||
@if STM32F103xx
|
||||
* @arg @ref RCC_PERIPHCLK_USB USB peripheral clock
|
||||
@endif
|
||||
* @retval Frequency in Hz (0: means that no available frequency for the peripheral)
|
||||
*/
|
||||
uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
|
||||
{
|
||||
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|
||||
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|
||||
|| defined(STM32F105xC) || defined(STM32F107xC)
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13};
|
||||
const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};
|
||||
#else
|
||||
const uint8_t aPLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};
|
||||
const uint8_t aPredivFactorTable[2] = { 1, 2};
|
||||
#endif
|
||||
#endif
|
||||
uint32_t temp_reg = 0, frequency = 0;
|
||||
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|
||||
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|
||||
|| defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1 = 0, pllclk = 0, pllmul = 0;
|
||||
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t pll2mul = 0, pll3mul = 0, prediv2 = 0;
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
|
||||
|
||||
switch (PeriphClk)
|
||||
{
|
||||
#if defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6)\
|
||||
|| defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG)\
|
||||
|| defined(STM32F105xC) || defined(STM32F107xC)
|
||||
case RCC_PERIPHCLK_USB:
|
||||
{
|
||||
/* Get RCC configuration ------------------------------------------------------*/
|
||||
temp_reg = RCC->CFGR;
|
||||
|
||||
/* Check if PLL is enabled */
|
||||
if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLLON))
|
||||
{
|
||||
pllmul = aPLLMULFactorTable[(uint32_t)(temp_reg & RCC_CFGR_PLLMULL) >> POSITION_VAL(RCC_CFGR_PLLMULL)];
|
||||
if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
|
||||
{
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC) || defined(STM32F100xB)\
|
||||
|| defined(STM32F100xE)
|
||||
prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> POSITION_VAL(RCC_CFGR2_PREDIV1)];
|
||||
#else
|
||||
prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> POSITION_VAL(RCC_CFGR_PLLXTPRE)];
|
||||
#endif /* STM32F105xC || STM32F107xC || STM32F100xB || STM32F100xE */
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC))
|
||||
{
|
||||
/* PLL2 selected as Prediv1 source */
|
||||
/* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */
|
||||
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
|
||||
pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> POSITION_VAL(RCC_CFGR2_PLL2MUL)) + 2;
|
||||
pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
|
||||
pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
|
||||
}
|
||||
|
||||
/* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */
|
||||
/* In this case need to divide pllclk by 2 */
|
||||
if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)])
|
||||
{
|
||||
pllclk = pllclk / 2;
|
||||
}
|
||||
#else
|
||||
if ((temp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)
|
||||
{
|
||||
/* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */
|
||||
pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul);
|
||||
}
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */
|
||||
pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul);
|
||||
}
|
||||
|
||||
/* Calcul of the USB frequency*/
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/* USBCLK = PLLVCO = (2 x PLLCLK) / USB prescaler */
|
||||
if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL_DIV2)
|
||||
{
|
||||
/* Prescaler of 2 selected for USB */
|
||||
frequency = pllclk;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prescaler of 3 selected for USB */
|
||||
frequency = (2 * pllclk) / 3;
|
||||
}
|
||||
#else
|
||||
/* USBCLK = PLLCLK / USB prescaler */
|
||||
if (__HAL_RCC_GET_USB_SOURCE() == RCC_USBCLKSOURCE_PLL)
|
||||
{
|
||||
/* No prescaler selected for USB */
|
||||
frequency = pllclk;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Prescaler of 1.5 selected for USB */
|
||||
frequency = (pllclk * 2) / 3;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif /* STM32F102x6 || STM32F102xB || STM32F103x6 || STM32F103xB || STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
|
||||
#if defined(STM32F103xE) || defined(STM32F103xG) || defined(STM32F105xC)\
|
||||
|| defined(STM32F107xC)
|
||||
case RCC_PERIPHCLK_I2S2:
|
||||
{
|
||||
#if defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* SYSCLK used as source clock for I2S2 */
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
#else
|
||||
if (__HAL_RCC_GET_I2S2_SOURCE() == RCC_I2S2CLKSOURCE_SYSCLK)
|
||||
{
|
||||
/* SYSCLK used as source clock for I2S2 */
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if PLLI2S is enabled */
|
||||
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
|
||||
{
|
||||
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
|
||||
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
|
||||
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
|
||||
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
|
||||
}
|
||||
}
|
||||
#endif /* STM32F103xE || STM32F103xG */
|
||||
break;
|
||||
}
|
||||
case RCC_PERIPHCLK_I2S3:
|
||||
{
|
||||
#if defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* SYSCLK used as source clock for I2S3 */
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
#else
|
||||
if (__HAL_RCC_GET_I2S3_SOURCE() == RCC_I2S3CLKSOURCE_SYSCLK)
|
||||
{
|
||||
/* SYSCLK used as source clock for I2S3 */
|
||||
frequency = HAL_RCC_GetSysClockFreq();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if PLLI2S is enabled */
|
||||
if (HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLL3ON))
|
||||
{
|
||||
/* PLLI2SVCO = 2 * PLLI2SCLK = 2 * (HSE/PREDIV2 * PLL3MUL) */
|
||||
prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1;
|
||||
pll3mul = ((RCC->CFGR2 & RCC_CFGR2_PLL3MUL) >> POSITION_VAL(RCC_CFGR2_PLL3MUL)) + 2;
|
||||
frequency = (uint32_t)(2 * ((HSE_VALUE / prediv2) * pll3mul));
|
||||
}
|
||||
}
|
||||
#endif /* STM32F103xE || STM32F103xG */
|
||||
break;
|
||||
}
|
||||
#endif /* STM32F103xE || STM32F103xG || STM32F105xC || STM32F107xC */
|
||||
case RCC_PERIPHCLK_RTC:
|
||||
{
|
||||
/* Get RCC BDCR configuration ------------------------------------------------------*/
|
||||
temp_reg = RCC->BDCR;
|
||||
|
||||
/* Check if LSE is ready if RTC clock selection is LSE */
|
||||
if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(temp_reg, RCC_BDCR_LSERDY)))
|
||||
{
|
||||
frequency = LSE_VALUE;
|
||||
}
|
||||
/* Check if LSI is ready if RTC clock selection is LSI */
|
||||
else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
|
||||
{
|
||||
frequency = LSI_VALUE;
|
||||
}
|
||||
else if (((temp_reg & RCC_BDCR_RTCSEL) == RCC_RTCCLKSOURCE_HSE_DIV128) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
|
||||
{
|
||||
frequency = HSE_VALUE / 128;
|
||||
}
|
||||
/* Clock not enabled for RTC*/
|
||||
else
|
||||
{
|
||||
frequency = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RCC_PERIPHCLK_ADC:
|
||||
{
|
||||
frequency = HAL_RCC_GetPCLK2Freq() / (((__HAL_RCC_GET_ADC_SOURCE() >> POSITION_VAL(RCC_CFGR_ADCPRE_DIV4)) + 1) * 2);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return(frequency);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
/** @defgroup RCCEx_Exported_Functions_Group2 PLLI2S Management function
|
||||
* @brief PLLI2S Management functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended PLLI2S Management functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the PLLI2S
|
||||
activation or deactivation
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable PLLI2S
|
||||
* @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that
|
||||
* contains the configuration information for the PLLI2S
|
||||
* @note The PLLI2S configuration not modified if used by I2S2 or I2S3 Interface.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit)
|
||||
{
|
||||
uint32_t tickstart = 0;
|
||||
|
||||
/* Check that PLL I2S has not been already enabled by I2S2 or I2S3*/
|
||||
if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLLI2S_MUL(PLLI2SInit->PLLI2SMUL));
|
||||
assert_param(IS_RCC_HSE_PREDIV2(PLLI2SInit->HSEPrediv2Value));
|
||||
|
||||
/* Prediv2 can be written only when the PLL2 is disabled. */
|
||||
/* Return an error only if new value is different from the programmed value */
|
||||
if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL2ON) && \
|
||||
(__HAL_RCC_HSE_GET_PREDIV2() != PLLI2SInit->HSEPrediv2Value))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Disable the main PLLI2S. */
|
||||
__HAL_RCC_PLLI2S_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLI2S is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the HSE prediv2 factor --------------------------------*/
|
||||
__HAL_RCC_HSE_PREDIV2_CONFIG(PLLI2SInit->HSEPrediv2Value);
|
||||
|
||||
|
||||
/* Configure the main PLLI2S multiplication factors. */
|
||||
__HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SMUL);
|
||||
|
||||
/* Enable the main PLLI2S. */
|
||||
__HAL_RCC_PLLI2S_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLI2S is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLLI2S cannot be modified as already used by I2S2 or I2S3 */
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable PLLI2S
|
||||
* @note PLLI2S is not disabled if used by I2S2 or I2S3 Interface.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void)
|
||||
{
|
||||
uint32_t tickstart = 0;
|
||||
|
||||
/* Disable PLL I2S as not requested by I2S2 or I2S3*/
|
||||
if (HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S2SRC) && HAL_IS_BIT_CLR(RCC->CFGR2, RCC_CFGR2_I2S3SRC))
|
||||
{
|
||||
/* Disable the main PLLI2S. */
|
||||
__HAL_RCC_PLLI2S_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLLI2S is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* PLLI2S is currently used by I2S2 or I2S3. Cannot be disabled.*/
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup RCCEx_Exported_Functions_Group3 PLL2 Management function
|
||||
* @brief PLL2 Management functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Extended PLL2 Management functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection provides a set of functions allowing to control the PLL2
|
||||
activation or deactivation
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Enable PLL2
|
||||
* @param PLL2Init pointer to an RCC_PLL2InitTypeDef structure that
|
||||
* contains the configuration information for the PLL2
|
||||
* @note The PLL2 configuration not modified if used indirectly as system clock.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_EnablePLL2(RCC_PLL2InitTypeDef *PLL2Init)
|
||||
{
|
||||
uint32_t tickstart = 0;
|
||||
|
||||
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
|
||||
clock (i.e. it is used as PLL clock entry that is used as system clock). */
|
||||
if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
|
||||
(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
|
||||
((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_RCC_PLL2_MUL(PLL2Init->PLL2MUL));
|
||||
assert_param(IS_RCC_HSE_PREDIV2(PLL2Init->HSEPrediv2Value));
|
||||
|
||||
/* Prediv2 can be written only when the PLLI2S is disabled. */
|
||||
/* Return an error only if new value is different from the programmed value */
|
||||
if (HAL_IS_BIT_SET(RCC->CR,RCC_CR_PLL3ON) && \
|
||||
(__HAL_RCC_HSE_GET_PREDIV2() != PLL2Init->HSEPrediv2Value))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Disable the main PLL2. */
|
||||
__HAL_RCC_PLL2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL2 is disabled */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Configure the HSE prediv2 factor --------------------------------*/
|
||||
__HAL_RCC_HSE_PREDIV2_CONFIG(PLL2Init->HSEPrediv2Value);
|
||||
|
||||
/* Configure the main PLL2 multiplication factors. */
|
||||
__HAL_RCC_PLL2_CONFIG(PLL2Init->PLL2MUL);
|
||||
|
||||
/* Enable the main PLL2. */
|
||||
__HAL_RCC_PLL2_ENABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL2 is ready */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) == RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable PLL2
|
||||
* @note PLL2 is not disabled if used indirectly as system clock.
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_RCCEx_DisablePLL2(void)
|
||||
{
|
||||
uint32_t tickstart = 0;
|
||||
|
||||
/* This bit can not be cleared if the PLL2 clock is used indirectly as system
|
||||
clock (i.e. it is used as PLL clock entry that is used as system clock). */
|
||||
if((__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) && \
|
||||
(__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_SYSCLKSOURCE_STATUS_PLLCLK) && \
|
||||
((READ_BIT(RCC->CFGR2,RCC_CFGR2_PREDIV1SRC)) == RCC_CFGR2_PREDIV1SRC_PLL2))
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Disable the main PLL2. */
|
||||
__HAL_RCC_PLL2_DISABLE();
|
||||
|
||||
/* Get Start Tick*/
|
||||
tickstart = HAL_GetTick();
|
||||
|
||||
/* Wait till PLL2 is disabled */
|
||||
while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLL2RDY) != RESET)
|
||||
{
|
||||
if((HAL_GetTick() - tickstart ) > PLL2_TIMEOUT_VALUE)
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* STM32F105xC || STM32F107xC */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
2410
system/src/stm32f1xx/stm32f1xx_hal_spi.c
Normal file
2410
system/src/stm32f1xx/stm32f1xx_hal_spi.c
Normal file
File diff suppressed because it is too large
Load Diff
217
system/src/stm32f1xx/stm32f1xx_hal_spi_ex.c
Normal file
217
system/src/stm32f1xx/stm32f1xx_hal_spi_ex.c
Normal file
@ -0,0 +1,217 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_spi_ex.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.4
|
||||
* @date 29-April-2016
|
||||
* @brief Extended SPI HAL module driver.
|
||||
*
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities SPI extension peripheral:
|
||||
* + Extended Peripheral Control functions
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F1xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI
|
||||
* @{
|
||||
*/
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
|
||||
/** @defgroup SPI_Private_Variables SPI Private Variables
|
||||
* @{
|
||||
*/
|
||||
/* Variable used to determine if device is impacted by implementation of workaround
|
||||
related to wrong CRC errors detection on SPI2. Conditions in which this workaround has to be applied, are:
|
||||
- STM32F101CDE/STM32F103CDE
|
||||
- Revision ID : Z
|
||||
- SPI2
|
||||
- In receive only mode, with CRC calculation enabled, at the end of the CRC reception,
|
||||
the software needs to check the CRCERR flag. If it is found set, read back the SPI_RXCRC:
|
||||
+ If the value is 0, the complete data transfer is successful.
|
||||
+ Otherwise, one or more errors have been detected during the data transfer by CPU or DMA.
|
||||
If CRCERR is found reset, the complete data transfer is considered successful.
|
||||
*/
|
||||
uint8_t uCRCErrorWorkaroundCheck = 0;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* Private functions ---------------------------------------------------------*/
|
||||
|
||||
/** @addtogroup SPI_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI_Exported_Functions_Group1
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initializes the SPI according to the specified parameters
|
||||
* in the SPI_InitTypeDef and create 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_MODE(hspi->Init.Direction));
|
||||
assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
|
||||
assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
|
||||
assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
|
||||
assert_param(IS_SPI_NSS(hspi->Init.NSS));
|
||||
assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
|
||||
assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
|
||||
assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
|
||||
assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
|
||||
assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
|
||||
|
||||
if(hspi->State == HAL_SPI_STATE_RESET)
|
||||
{
|
||||
/* Init the low level hardware : GPIO, CLOCK, NVIC... */
|
||||
HAL_SPI_MspInit(hspi);
|
||||
}
|
||||
|
||||
hspi->State = HAL_SPI_STATE_BUSY;
|
||||
|
||||
/* Disble the selected SPI peripheral */
|
||||
__HAL_SPI_DISABLE(hspi);
|
||||
|
||||
/*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
|
||||
/* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
|
||||
Communication speed, First bit and CRC calculation state */
|
||||
WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
|
||||
hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
|
||||
hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit | hspi->Init.CRCCalculation) );
|
||||
|
||||
/* Configure : NSS management */
|
||||
WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16) & SPI_CR2_SSOE) | hspi->Init.TIMode));
|
||||
|
||||
/*---------------------------- SPIx CRCPOLY Configuration ------------------*/
|
||||
/* Configure : CRC Polynomial */
|
||||
WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
|
||||
|
||||
#if defined (STM32F101x6) || defined (STM32F101xB) || defined (STM32F101xE) || defined (STM32F101xG) || defined (STM32F102x6) || defined (STM32F102xB) || defined (STM32F103x6) || defined (STM32F103xB) || defined (STM32F103xE) || defined (STM32F103xG) || defined (STM32F105xC) || defined (STM32F107xC)
|
||||
/* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
|
||||
CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
|
||||
#endif
|
||||
|
||||
#if defined (STM32F101xE) || defined (STM32F103xE)
|
||||
/* Check RevisionID value for identifying if Device is Rev Z (0x0001) in order to enable workaround for
|
||||
CRC errors wrongly detected */
|
||||
/* Pb is that ES_STM32F10xxCDE also identify an issue in Debug registers access while not in Debug mode.
|
||||
Revision ID information is only available in Debug mode, so Workaround could not be implemented
|
||||
to distinguish Rev Z devices (issue present) from more recent version (issue fixed).
|
||||
So, in case of Revison Z F101 or F103 devices, below variable should be assigned to 1 */
|
||||
uCRCErrorWorkaroundCheck = 0;
|
||||
#else
|
||||
uCRCErrorWorkaroundCheck = 0;
|
||||
#endif
|
||||
|
||||
hspi->ErrorCode = HAL_SPI_ERROR_NONE;
|
||||
hspi->State = HAL_SPI_STATE_READY;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Checks if encountered CRC error could be corresponding to wrongly detected errors
|
||||
* according to SPI instance, Device type, and revision ID.
|
||||
* @param hspi: pointer to a SPI_HandleTypeDef structure that contains
|
||||
* the configuration information for SPI module.
|
||||
* @retval CRC error validity (SPI_INVALID_CRC_ERROR or SPI_VALID_CRC_ERROR).
|
||||
*/
|
||||
uint8_t SPI_ISCRCErrorValid(SPI_HandleTypeDef *hspi)
|
||||
{
|
||||
#if defined (STM32F101xE) || defined (STM32F103xE)
|
||||
/* Check how to handle this CRC error (workaround to be applied or not) */
|
||||
/* If CRC errors could be wrongly detected (issue 2.15.2 in STM32F10xxC/D/E silicon limitations ES (DocID14732 Rev 13) */
|
||||
if ( (uCRCErrorWorkaroundCheck != 0) && (hspi->Instance == SPI2) )
|
||||
{
|
||||
if (hspi->Instance->RXCRCR == 0)
|
||||
{
|
||||
return (SPI_INVALID_CRC_ERROR);
|
||||
}
|
||||
}
|
||||
return (SPI_VALID_CRC_ERROR);
|
||||
#else
|
||||
return (SPI_VALID_CRC_ERROR);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
5379
system/src/stm32f1xx/stm32f1xx_hal_tim.c
Normal file
5379
system/src/stm32f1xx/stm32f1xx_hal_tim.c
Normal file
File diff suppressed because it is too large
Load Diff
1857
system/src/stm32f1xx/stm32f1xx_hal_tim_ex.c
Normal file
1857
system/src/stm32f1xx/stm32f1xx_hal_tim_ex.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user