Add template with port setups and a few blinking LEDs to test the hardware
This commit is contained in:
commit
b118a010e3
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*.o
|
||||||
|
*.map
|
||||||
|
*.elf
|
||||||
|
*.lss
|
||||||
|
*.d
|
92
Makefile
Normal file
92
Makefile
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
################################Shimatta Makefile####################################
|
||||||
|
#CPU: STM32F030F4P6
|
||||||
|
#Compiler: arm-none-eabi
|
||||||
|
#####################################################################################
|
||||||
|
|
||||||
|
ifneq ($(VERBOSE),true)
|
||||||
|
QUIET=@
|
||||||
|
else
|
||||||
|
QUIET=
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
#Add Files and Folders below#########################################################
|
||||||
|
CFILES = main.c setup/system_init.c startup/startup_stm32f0xx.c systick.c
|
||||||
|
ASFILES =
|
||||||
|
INCLUDEPATH = -Iinclude -Iinclude/cmsis
|
||||||
|
|
||||||
|
OBJDIR=obj
|
||||||
|
target = remote
|
||||||
|
LIBRARYPATH = -Lstartup
|
||||||
|
LIBRARIES =
|
||||||
|
|
||||||
|
DEFINES = -DSTM32F030x6 -DSTM32F0XX
|
||||||
|
mapfile = memmap
|
||||||
|
|
||||||
|
##Custom Files###
|
||||||
|
|
||||||
|
#TODO
|
||||||
|
|
||||||
|
|
||||||
|
###################################################################################
|
||||||
|
CROSS_COMPILE ?= arm-none-eabi-
|
||||||
|
CC := $(CROSS_COMPILE)gcc
|
||||||
|
OBJCOPY := $(CROSS_COMPILE)objcopy
|
||||||
|
OBJDUMP := $(CROSS_COMPILE)objdump
|
||||||
|
SIZE := $(CROSS_COMPILE)size
|
||||||
|
|
||||||
|
LFLAGS = -mlittle-endian -mthumb -mcpu=cortex-m0 -mthumb-interwork
|
||||||
|
LFLAGS += -mfloat-abi=soft --disable-newlib-supplied-syscalls -nostartfiles
|
||||||
|
LFLAGS += -Tstartup/stm32f030.ld -Wl,-Map=$(mapfile).map -Wl,--gc-sections -Wl,--print-memory-usage -g
|
||||||
|
|
||||||
|
CFLAGS = -c -fmessage-length=0 -mlittle-endian -mthumb -mcpu=cortex-m0 -mthumb-interwork
|
||||||
|
CFLAGS += -mfloat-abi=soft -nostartfiles -Wall -g3 -O0
|
||||||
|
|
||||||
|
####################################################################################
|
||||||
|
|
||||||
|
OBJ = $(CFILES:%.c=$(OBJDIR)/%.c.o)
|
||||||
|
ASOBJ = $(ASFILES:%.S=$(OBJDIR)/%.S.o)
|
||||||
|
|
||||||
|
default: $(target).elf
|
||||||
|
|
||||||
|
%.bin: %.elf
|
||||||
|
$(OBJCOPY) -O binary $^ $@
|
||||||
|
%.hex: %.elf
|
||||||
|
$(OBJCOPY) -O ihex $^ $@
|
||||||
|
|
||||||
|
#Linking
|
||||||
|
$(target).elf: $(OBJ) $(ASOBJ)
|
||||||
|
@echo Linking $@
|
||||||
|
$(QUIET)$(CC) $(LFLAGS) $(LIBRARYPATH) -o $@ $^ $(LIBRARIES)
|
||||||
|
$(QUIET)$(SIZE) $@
|
||||||
|
|
||||||
|
#Compiling
|
||||||
|
$(OBJ):
|
||||||
|
@echo [CC] $@
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
$(QUIET)$(CC) $(CFLAGS) -MMD -MT $@ $(INCLUDEPATH) $(DEFINES) -o $@ $(@:$(OBJDIR)/%.c.o=%.c)
|
||||||
|
|
||||||
|
$(ASOBJ):
|
||||||
|
@echo [AS] $@
|
||||||
|
@mkdir -p $(@D)
|
||||||
|
$(QUIET)$(CC) $(CFLAGS) -MMD -MT $@ $(INCLUDEPATH) $(DEFINES) -o $@ $(@:$(OBJDIR)/%.S.o=%.S)
|
||||||
|
|
||||||
|
.PHONY: clean mrproper objcopy disassemble binary
|
||||||
|
|
||||||
|
disassemble: $(target).elf
|
||||||
|
$(OBJDUMP) -D -s $< > $(target).lss
|
||||||
|
|
||||||
|
objcopy: $(target).bin $(target).hex
|
||||||
|
|
||||||
|
mrproper:
|
||||||
|
rm -f $(target).pro
|
||||||
|
|
||||||
|
binary: $(target).bin $(target).hex
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo [CLEAN] $(OBJDIR)
|
||||||
|
@rm -f $(target).elf $(target).bin $(target).hex $(OBJ) $(ASOBJ) $(mapfile).map $(target).lss
|
||||||
|
@rm -rf $(OBJDIR)/*
|
||||||
|
|
||||||
|
-include $(CFILES:%.c=$(OBJDIR)/%.c.d) $(ASFILES:%.S=$(OBJDIR)/%.S.d)
|
||||||
|
|
740
include/cmsis/core_cm0.h
Normal file
740
include/cmsis/core_cm0.h
Normal file
@ -0,0 +1,740 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cm0.h
|
||||||
|
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- 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.
|
||||||
|
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0_H_GENERIC
|
||||||
|
#define __CORE_CM0_H_GENERIC
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||||
|
CMSIS violates the following MISRA-C:2004 rules:
|
||||||
|
|
||||||
|
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||||
|
Function definitions in header files are used to allow 'inlining'.
|
||||||
|
|
||||||
|
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||||
|
Unions are used for effective representation of core registers.
|
||||||
|
|
||||||
|
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||||
|
Function-like macros are used to allow more efficient code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* CMSIS definitions
|
||||||
|
******************************************************************************/
|
||||||
|
/** \ingroup Cortex_M0
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* CMSIS CM0 definitions */
|
||||||
|
#define __CM0_CMSIS_VERSION_MAIN (0x04) /*!< [31:16] CMSIS HAL main version */
|
||||||
|
#define __CM0_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */
|
||||||
|
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | \
|
||||||
|
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||||
|
|
||||||
|
#define __CORTEX_M (0x00) /*!< Cortex-M Core */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||||
|
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||||
|
#define __STATIC_INLINE static __inline
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||||
|
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ )
|
||||||
|
#define __packed
|
||||||
|
#define __ASM _asm /*!< asm keyword for COSMIC Compiler */
|
||||||
|
#define __INLINE inline /*use -pc99 on compile line !< inline keyword for COSMIC Compiler */
|
||||||
|
#define __STATIC_INLINE static inline
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** __FPU_USED indicates whether an FPU is used or not.
|
||||||
|
This core does not support an FPU at all
|
||||||
|
*/
|
||||||
|
#define __FPU_USED 0
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM )
|
||||||
|
#if defined __TARGET_FPU_VFP
|
||||||
|
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ )
|
||||||
|
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||||
|
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ )
|
||||||
|
#if defined __ARMVFP__
|
||||||
|
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ )
|
||||||
|
#if defined __TI__VFP_SUPPORT____
|
||||||
|
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ )
|
||||||
|
#if defined __FPU_VFP__
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /* Cosmic */
|
||||||
|
#if ( __CSMC__ & 0x400) // FPU present for parser
|
||||||
|
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h> /* standard types definitions */
|
||||||
|
#include <cmsis/core_cmInstr.h> /* Core Instruction Access */
|
||||||
|
#include <cmsis/core_cmFunc.h> /* Core Function Access */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0_H_GENERIC */
|
||||||
|
|
||||||
|
#ifndef __CMSIS_GENERIC
|
||||||
|
|
||||||
|
#ifndef __CORE_CM0_H_DEPENDANT
|
||||||
|
#define __CORE_CM0_H_DEPENDANT
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check device defines and use defaults */
|
||||||
|
#if defined __CHECK_DEVICE_DEFINES
|
||||||
|
#ifndef __CM0_REV
|
||||||
|
#define __CM0_REV 0x0000
|
||||||
|
#warning "__CM0_REV not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __NVIC_PRIO_BITS
|
||||||
|
#define __NVIC_PRIO_BITS 2
|
||||||
|
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __Vendor_SysTickConfig
|
||||||
|
#define __Vendor_SysTickConfig 0
|
||||||
|
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* IO definitions (access restrictions to peripheral registers) */
|
||||||
|
/**
|
||||||
|
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||||
|
|
||||||
|
<strong>IO Type Qualifiers</strong> are used
|
||||||
|
\li to specify the access to peripheral variables.
|
||||||
|
\li for automatic generation of peripheral register debug information.
|
||||||
|
*/
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define __I volatile /*!< Defines 'read only' permissions */
|
||||||
|
#else
|
||||||
|
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||||
|
#endif
|
||||||
|
#define __O volatile /*!< Defines 'write only' permissions */
|
||||||
|
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||||
|
|
||||||
|
/*@} end of group Cortex_M0 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Register Abstraction
|
||||||
|
Core Register contain:
|
||||||
|
- Core Register
|
||||||
|
- Core NVIC Register
|
||||||
|
- Core SCB Register
|
||||||
|
- Core SysTick Register
|
||||||
|
******************************************************************************/
|
||||||
|
/** \defgroup CMSIS_core_register Defines and Type Definitions
|
||||||
|
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CORE Status and Control Registers
|
||||||
|
\brief Core Register type definitions.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Union type to access the Application Program Status Register (APSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} APSR_Type;
|
||||||
|
|
||||||
|
/* APSR Register Definitions */
|
||||||
|
#define APSR_N_Pos 31 /*!< APSR: N Position */
|
||||||
|
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||||
|
|
||||||
|
#define APSR_Z_Pos 30 /*!< APSR: Z Position */
|
||||||
|
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||||
|
|
||||||
|
#define APSR_C_Pos 29 /*!< APSR: C Position */
|
||||||
|
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||||
|
|
||||||
|
#define APSR_V_Pos 28 /*!< APSR: V Position */
|
||||||
|
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} IPSR_Type;
|
||||||
|
|
||||||
|
/* IPSR Register Definitions */
|
||||||
|
#define IPSR_ISR_Pos 0 /*!< IPSR: ISR Position */
|
||||||
|
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||||
|
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||||
|
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||||
|
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||||
|
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||||
|
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||||
|
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||||
|
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} xPSR_Type;
|
||||||
|
|
||||||
|
/* xPSR Register Definitions */
|
||||||
|
#define xPSR_N_Pos 31 /*!< xPSR: N Position */
|
||||||
|
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||||
|
|
||||||
|
#define xPSR_Z_Pos 30 /*!< xPSR: Z Position */
|
||||||
|
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||||
|
|
||||||
|
#define xPSR_C_Pos 29 /*!< xPSR: C Position */
|
||||||
|
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||||
|
|
||||||
|
#define xPSR_V_Pos 28 /*!< xPSR: V Position */
|
||||||
|
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||||
|
|
||||||
|
#define xPSR_T_Pos 24 /*!< xPSR: T Position */
|
||||||
|
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||||
|
|
||||||
|
#define xPSR_ISR_Pos 0 /*!< xPSR: ISR Position */
|
||||||
|
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Union type to access the Control Registers (CONTROL).
|
||||||
|
*/
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||||
|
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||||
|
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||||
|
} b; /*!< Structure used for bit access */
|
||||||
|
uint32_t w; /*!< Type used for word access */
|
||||||
|
} CONTROL_Type;
|
||||||
|
|
||||||
|
/* CONTROL Register Definitions */
|
||||||
|
#define CONTROL_SPSEL_Pos 1 /*!< CONTROL: SPSEL Position */
|
||||||
|
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_CORE */
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||||
|
\brief Type definitions for the NVIC Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||||
|
uint32_t RESERVED0[31];
|
||||||
|
__IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||||
|
uint32_t RSERVED1[31];
|
||||||
|
__IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||||
|
uint32_t RESERVED2[31];
|
||||||
|
__IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||||
|
uint32_t RESERVED3[31];
|
||||||
|
uint32_t RESERVED4[64];
|
||||||
|
__IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||||
|
} NVIC_Type;
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_NVIC */
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||||
|
\brief Type definitions for the System Control Block Registers
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Structure type to access the System Control Block (SCB).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||||
|
__IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||||
|
uint32_t RESERVED0;
|
||||||
|
__IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||||
|
__IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||||
|
__IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||||
|
uint32_t RESERVED1;
|
||||||
|
__IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||||
|
__IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||||
|
} SCB_Type;
|
||||||
|
|
||||||
|
/* SCB CPUID Register Definitions */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */
|
||||||
|
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */
|
||||||
|
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */
|
||||||
|
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */
|
||||||
|
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||||
|
|
||||||
|
#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */
|
||||||
|
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||||
|
|
||||||
|
/* SCB Interrupt Control State Register Definitions */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */
|
||||||
|
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */
|
||||||
|
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */
|
||||||
|
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */
|
||||||
|
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */
|
||||||
|
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */
|
||||||
|
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */
|
||||||
|
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||||
|
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */
|
||||||
|
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */
|
||||||
|
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||||
|
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */
|
||||||
|
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||||
|
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||||
|
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||||
|
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||||
|
|
||||||
|
/* SCB System Control Register Definitions */
|
||||||
|
#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */
|
||||||
|
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */
|
||||||
|
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||||
|
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */
|
||||||
|
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||||
|
|
||||||
|
/* SCB Configuration Control Register Definitions */
|
||||||
|
#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */
|
||||||
|
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||||
|
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */
|
||||||
|
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||||
|
|
||||||
|
/* SCB System Handler Control and State Register Definitions */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||||
|
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SCB */
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||||
|
\brief Type definitions for the System Timer Registers.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** \brief Structure type to access the System Timer (SysTick).
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
__IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||||
|
__IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||||
|
__IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||||
|
__I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||||
|
} SysTick_Type;
|
||||||
|
|
||||||
|
/* SysTick Control / Status Register Definitions */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */
|
||||||
|
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */
|
||||||
|
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */
|
||||||
|
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||||
|
|
||||||
|
#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */
|
||||||
|
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||||
|
|
||||||
|
/* SysTick Reload Register Definitions */
|
||||||
|
#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */
|
||||||
|
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||||
|
|
||||||
|
/* SysTick Current Register Definitions */
|
||||||
|
#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */
|
||||||
|
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||||
|
|
||||||
|
/* SysTick Calibration Register Definitions */
|
||||||
|
#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */
|
||||||
|
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */
|
||||||
|
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||||
|
|
||||||
|
#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */
|
||||||
|
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SysTick */
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||||
|
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR)
|
||||||
|
are only accessible over DAP and not via processor. Therefore
|
||||||
|
they are not covered by the Cortex-M0 header file.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
/*@} end of group CMSIS_CoreDebug */
|
||||||
|
|
||||||
|
|
||||||
|
/** \ingroup CMSIS_core_register
|
||||||
|
\defgroup CMSIS_core_base Core Definitions
|
||||||
|
\brief Definitions for base addresses, unions, and structures.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Memory mapping of Cortex-M0 Hardware */
|
||||||
|
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||||
|
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||||
|
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||||
|
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||||
|
|
||||||
|
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||||
|
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||||
|
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||||
|
|
||||||
|
|
||||||
|
/*@} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
Core Function Interface contains:
|
||||||
|
- Core NVIC Functions
|
||||||
|
- Core SysTick Functions
|
||||||
|
- Core Register Access Functions
|
||||||
|
******************************************************************************/
|
||||||
|
/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## NVIC functions #################################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||||
|
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Interrupt Priorities are WORD accessible only under ARMv6M */
|
||||||
|
/* The following MACROS handle generation of the register offset and byte masks */
|
||||||
|
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||||
|
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||||
|
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Enable External Interrupt
|
||||||
|
|
||||||
|
The function enables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable External Interrupt
|
||||||
|
|
||||||
|
The function disables a device-specific interrupt in the NVIC interrupt controller.
|
||||||
|
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICER[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Pending Interrupt
|
||||||
|
|
||||||
|
The function reads the pending register in the NVIC and returns the pending bit
|
||||||
|
for the specified interrupt.
|
||||||
|
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
|
||||||
|
\return 0 Interrupt status is not pending.
|
||||||
|
\return 1 Interrupt status is pending.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
return((uint32_t)(((NVIC->ISPR[0] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Pending Interrupt
|
||||||
|
|
||||||
|
The function sets the pending bit of an external interrupt.
|
||||||
|
|
||||||
|
\param [in] IRQn Interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ISPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Clear Pending Interrupt
|
||||||
|
|
||||||
|
The function clears the pending bit of an external interrupt.
|
||||||
|
|
||||||
|
\param [in] IRQn External interrupt number. Value cannot be negative.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
NVIC->ICPR[0] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Interrupt Priority
|
||||||
|
|
||||||
|
The function sets the priority of an interrupt.
|
||||||
|
|
||||||
|
\note The priority cannot be set for every core interrupt.
|
||||||
|
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\param [in] priority Priority to set.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||||
|
{
|
||||||
|
if((int32_t)(IRQn) < 0) {
|
||||||
|
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||||
|
(((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Interrupt Priority
|
||||||
|
|
||||||
|
The function reads the priority of an interrupt. The interrupt
|
||||||
|
number can be positive to specify an external (device specific)
|
||||||
|
interrupt, or negative to specify an internal (core) interrupt.
|
||||||
|
|
||||||
|
|
||||||
|
\param [in] IRQn Interrupt number.
|
||||||
|
\return Interrupt Priority. Value is aligned automatically to the implemented
|
||||||
|
priority bits of the microcontroller.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
|
||||||
|
{
|
||||||
|
|
||||||
|
if((int32_t)(IRQn) < 0) {
|
||||||
|
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8 - __NVIC_PRIO_BITS)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief System Reset
|
||||||
|
|
||||||
|
The function initiates a system reset request to reset the MCU.
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void NVIC_SystemReset(void)
|
||||||
|
{
|
||||||
|
__DSB(); /* Ensure all outstanding memory accesses included
|
||||||
|
buffered write are completed before reset */
|
||||||
|
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||||
|
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||||
|
__DSB(); /* Ensure completion of memory access */
|
||||||
|
while(1) { __NOP(); } /* wait until reset */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_NVICFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ################################## SysTick function ############################################ */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||||
|
\brief Functions that configure the System.
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if (__Vendor_SysTickConfig == 0)
|
||||||
|
|
||||||
|
/** \brief System Tick Configuration
|
||||||
|
|
||||||
|
The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||||
|
Counter is in free running mode to generate periodic interrupts.
|
||||||
|
|
||||||
|
\param [in] ticks Number of ticks between two interrupts.
|
||||||
|
|
||||||
|
\return 0 Function succeeded.
|
||||||
|
\return 1 Function failed.
|
||||||
|
|
||||||
|
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||||
|
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||||
|
must contain a vendor-specific implementation of this function.
|
||||||
|
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||||
|
{
|
||||||
|
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); } /* Reload value impossible */
|
||||||
|
|
||||||
|
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||||
|
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||||
|
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||||
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||||
|
SysTick_CTRL_TICKINT_Msk |
|
||||||
|
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||||
|
return (0UL); /* Function successful */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||||
|
|
||||||
|
#endif /* __CMSIS_GENERIC */
|
664
include/cmsis/core_cmFunc.h
Normal file
664
include/cmsis/core_cmFunc.h
Normal file
@ -0,0 +1,664 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmFunc.h
|
||||||
|
* @brief CMSIS Cortex-M Core Function Access Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2015 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- 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.
|
||||||
|
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_CMFUNC_H
|
||||||
|
#define __CORE_CMFUNC_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################### Core Function Access ########################### */
|
||||||
|
/** \ingroup CMSIS_Core_FunctionInterface
|
||||||
|
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
|
||||||
|
#if (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* intrinsic void __enable_irq(); */
|
||||||
|
/* intrinsic void __disable_irq(); */
|
||||||
|
|
||||||
|
/** \brief Get Control Register
|
||||||
|
|
||||||
|
This function returns the content of the Control Register.
|
||||||
|
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
return(__regControl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Control Register
|
||||||
|
|
||||||
|
This function writes the given value to the Control Register.
|
||||||
|
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
register uint32_t __regControl __ASM("control");
|
||||||
|
__regControl = control;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get IPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the IPSR Register.
|
||||||
|
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regIPSR __ASM("ipsr");
|
||||||
|
return(__regIPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get APSR Register
|
||||||
|
|
||||||
|
This function returns the content of the APSR Register.
|
||||||
|
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regAPSR __ASM("apsr");
|
||||||
|
return(__regAPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get xPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the xPSR Register.
|
||||||
|
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regXPSR __ASM("xpsr");
|
||||||
|
return(__regXPSR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Process Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
return(__regProcessStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Process Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||||
|
__regProcessStackPointer = topOfProcStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Main Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
return(__regMainStackPointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Main Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
register uint32_t __regMainStackPointer __ASM("msp");
|
||||||
|
__regMainStackPointer = topOfMainStack;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Priority Mask
|
||||||
|
|
||||||
|
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
return(__regPriMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Priority Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Priority Mask Register.
|
||||||
|
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regPriMask __ASM("primask");
|
||||||
|
__regPriMask = (priMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief Enable FIQ
|
||||||
|
|
||||||
|
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __enable_fault_irq __enable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable FIQ
|
||||||
|
|
||||||
|
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
#define __disable_fault_irq __disable_fiq
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Base Priority
|
||||||
|
|
||||||
|
This function returns the current value of the Base Priority register.
|
||||||
|
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
return(__regBasePri);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePri __ASM("basepri");
|
||||||
|
__regBasePri = (basePri & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority with condition
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||||
|
{
|
||||||
|
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||||
|
__regBasePriMax = (basePri & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Fault Mask
|
||||||
|
|
||||||
|
This function returns the current value of the Fault Mask register.
|
||||||
|
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
return(__regFaultMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Fault Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Fault Mask register.
|
||||||
|
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
register uint32_t __regFaultMask __ASM("faultmask");
|
||||||
|
__regFaultMask = (faultMask & (uint32_t)1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
|
||||||
|
|
||||||
|
/** \brief Get FPSCR
|
||||||
|
|
||||||
|
This function returns the current value of the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
return(__regfpscr);
|
||||||
|
#else
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set FPSCR
|
||||||
|
|
||||||
|
This function assigns the given value to the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
register uint32_t __regfpscr __ASM("fpscr");
|
||||||
|
__regfpscr = (fpscr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
|
||||||
|
/** \brief Enable IRQ Interrupts
|
||||||
|
|
||||||
|
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable IRQ Interrupts
|
||||||
|
|
||||||
|
This function disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid i" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Control Register
|
||||||
|
|
||||||
|
This function returns the content of the Control Register.
|
||||||
|
|
||||||
|
\return Control Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, control" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Control Register
|
||||||
|
|
||||||
|
This function writes the given value to the Control Register.
|
||||||
|
|
||||||
|
\param [in] control Control Register value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get IPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the IPSR Register.
|
||||||
|
|
||||||
|
\return IPSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get APSR Register
|
||||||
|
|
||||||
|
This function returns the content of the APSR Register.
|
||||||
|
|
||||||
|
\return APSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get xPSR Register
|
||||||
|
|
||||||
|
This function returns the content of the xPSR Register.
|
||||||
|
|
||||||
|
\return xPSR Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Process Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\return PSP Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Process Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Process Stack Pointer (PSP).
|
||||||
|
|
||||||
|
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Main Stack Pointer
|
||||||
|
|
||||||
|
This function returns the current value of the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\return MSP Register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
|
||||||
|
{
|
||||||
|
register uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Main Stack Pointer
|
||||||
|
|
||||||
|
This function assigns the given value to the Main Stack Pointer (MSP).
|
||||||
|
|
||||||
|
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Priority Mask
|
||||||
|
|
||||||
|
This function returns the current state of the priority mask bit from the Priority Mask Register.
|
||||||
|
|
||||||
|
\return Priority Mask value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, primask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Priority Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Priority Mask Register.
|
||||||
|
|
||||||
|
\param [in] priMask Priority Mask
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03)
|
||||||
|
|
||||||
|
/** \brief Enable FIQ
|
||||||
|
|
||||||
|
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsie f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Disable FIQ
|
||||||
|
|
||||||
|
This function disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||||
|
Can only be executed in Privileged modes.
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("cpsid f" : : : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Base Priority
|
||||||
|
|
||||||
|
This function returns the current value of the Base Priority register.
|
||||||
|
|
||||||
|
\return Base Priority register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, basepri" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Base Priority with condition
|
||||||
|
|
||||||
|
This function assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||||
|
or the new value increases the BASEPRI priority level.
|
||||||
|
|
||||||
|
\param [in] basePri Base Priority value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Get Fault Mask
|
||||||
|
|
||||||
|
This function returns the current value of the Fault Mask register.
|
||||||
|
|
||||||
|
\return Fault Mask register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set Fault Mask
|
||||||
|
|
||||||
|
This function assigns the given value to the Fault Mask register.
|
||||||
|
|
||||||
|
\param [in] faultMask Fault Mask value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||||
|
{
|
||||||
|
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) */
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07)
|
||||||
|
|
||||||
|
/** \brief Get FPSCR
|
||||||
|
|
||||||
|
This function returns the current value of the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\return Floating Point Status/Control register value
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
/* Empty asm statement works as a scheduling barrier */
|
||||||
|
__ASM volatile ("");
|
||||||
|
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||||
|
__ASM volatile ("");
|
||||||
|
return(result);
|
||||||
|
#else
|
||||||
|
return(0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Set FPSCR
|
||||||
|
|
||||||
|
This function assigns the given value to the Floating Point Status/Control register.
|
||||||
|
|
||||||
|
\param [in] fpscr Floating Point Status/Control value to set
|
||||||
|
*/
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||||
|
{
|
||||||
|
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||||
|
/* Empty asm statement works as a scheduling barrier */
|
||||||
|
__ASM volatile ("");
|
||||||
|
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
|
||||||
|
__ASM volatile ("");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M == 0x04) || (__CORTEX_M == 0x07) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMFUNC_H */
|
916
include/cmsis/core_cmInstr.h
Normal file
916
include/cmsis/core_cmInstr.h
Normal file
@ -0,0 +1,916 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmInstr.h
|
||||||
|
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- 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.
|
||||||
|
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __CORE_CMINSTR_H
|
||||||
|
#define __CORE_CMINSTR_H
|
||||||
|
|
||||||
|
|
||||||
|
/* ########################## Core Instruction Access ######################### */
|
||||||
|
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||||
|
Access to dedicated instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
|
||||||
|
#if (__ARMCC_VERSION < 400677)
|
||||||
|
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief No Operation
|
||||||
|
|
||||||
|
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
#define __NOP __nop
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Interrupt
|
||||||
|
|
||||||
|
Wait For Interrupt is a hint instruction that suspends execution
|
||||||
|
until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFI __wfi
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Event
|
||||||
|
|
||||||
|
Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
#define __WFE __wfe
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Send Event
|
||||||
|
|
||||||
|
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
#define __SEV __sev
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Instruction Synchronization Barrier
|
||||||
|
|
||||||
|
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or
|
||||||
|
memory, after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
#define __ISB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__isb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Data Synchronization Barrier
|
||||||
|
|
||||||
|
This function acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
#define __DSB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dsb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Data Memory Barrier
|
||||||
|
|
||||||
|
This function ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
#define __DMB() do {\
|
||||||
|
__schedule_barrier();\
|
||||||
|
__dmb(0xF);\
|
||||||
|
__schedule_barrier();\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (32 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in integer value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#define __REV __rev
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (16 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in two unsigned short values.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
rev16 r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \brief Reverse byte order in signed short value
|
||||||
|
|
||||||
|
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||||
|
{
|
||||||
|
revsh r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right in unsigned value (32 bit)
|
||||||
|
|
||||||
|
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\param [in] value Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#define __ROR __ror
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Breakpoint
|
||||||
|
|
||||||
|
This function causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __breakpoint(value)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse bit order of value
|
||||||
|
|
||||||
|
This function reverses the bit order of the given value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
#define __RBIT __rbit
|
||||||
|
#else
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||||
|
|
||||||
|
result = value; // r will be reversed bits of v; first get LSB of v
|
||||||
|
for (value >>= 1; value; value >>= 1)
|
||||||
|
{
|
||||||
|
result <<= 1;
|
||||||
|
result |= value & 1;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; // shift when v's highest bits are zero
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Count leading zeros
|
||||||
|
|
||||||
|
This function counts the number of leading zeros of a data value.
|
||||||
|
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __clz
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Remove the exclusive lock
|
||||||
|
|
||||||
|
This function removes the exclusive lock which is created by LDREX.
|
||||||
|
|
||||||
|
*/
|
||||||
|
#define __CLREX __clrex
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Signed Saturate
|
||||||
|
|
||||||
|
This function saturates a signed value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT __ssat
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Unsigned Saturate
|
||||||
|
|
||||||
|
This function saturates an unsigned value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT __usat
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right with Extend (32 bit)
|
||||||
|
|
||||||
|
This function moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
#ifndef __NO_EMBEDDED_ASM
|
||||||
|
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
rrx r0, r0
|
||||||
|
bx lr
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
#define __STRT(value, ptr) __strt(value, ptr)
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
|
||||||
|
/* Define macros for porting to both thumb1 and thumb2.
|
||||||
|
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||||
|
* Otherwise, use general registers, specified by constrant "r" */
|
||||||
|
#if defined (__thumb__) && !defined (__thumb2__)
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||||
|
#else
|
||||||
|
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||||
|
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** \brief No Operation
|
||||||
|
|
||||||
|
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("nop");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Interrupt
|
||||||
|
|
||||||
|
Wait For Interrupt is a hint instruction that suspends execution
|
||||||
|
until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("wfi");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Wait For Event
|
||||||
|
|
||||||
|
Wait For Event is a hint instruction that permits the processor to enter
|
||||||
|
a low-power state until one of a number of events occurs.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("wfe");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Send Event
|
||||||
|
|
||||||
|
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("sev");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Instruction Synchronization Barrier
|
||||||
|
|
||||||
|
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||||
|
so that all instructions following the ISB are fetched from cache or
|
||||||
|
memory, after the instruction has been completed.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("isb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Data Synchronization Barrier
|
||||||
|
|
||||||
|
This function acts as a special kind of Data Memory Barrier.
|
||||||
|
It completes when all explicit memory accesses before this instruction complete.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dsb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Data Memory Barrier
|
||||||
|
|
||||||
|
This function ensures the apparent order of the explicit memory operations before
|
||||||
|
and after the instruction, without ensuring their completion.
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("dmb 0xF":::"memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (32 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in integer value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||||
|
return __builtin_bswap32(value);
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order (16 bit)
|
||||||
|
|
||||||
|
This function reverses the byte order in two unsigned short values.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse byte order in signed short value
|
||||||
|
|
||||||
|
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||||
|
{
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
return (short)__builtin_bswap16(value);
|
||||||
|
#else
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right in unsigned value (32 bit)
|
||||||
|
|
||||||
|
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\param [in] value Number of Bits to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
return (op1 >> op2) | (op1 << (32 - op2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Breakpoint
|
||||||
|
|
||||||
|
This function causes the processor to enter Debug state.
|
||||||
|
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||||
|
|
||||||
|
\param [in] value is ignored by the processor.
|
||||||
|
If required, a debugger can use it to store additional information about the breakpoint.
|
||||||
|
*/
|
||||||
|
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Reverse bit order of value
|
||||||
|
|
||||||
|
This function reverses the bit order of the given value.
|
||||||
|
|
||||||
|
\param [in] value Value to reverse
|
||||||
|
\return Reversed value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||||
|
#else
|
||||||
|
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||||
|
|
||||||
|
result = value; // r will be reversed bits of v; first get LSB of v
|
||||||
|
for (value >>= 1; value; value >>= 1)
|
||||||
|
{
|
||||||
|
result <<= 1;
|
||||||
|
result |= value & 1;
|
||||||
|
s--;
|
||||||
|
}
|
||||||
|
result <<= s; // shift when v's highest bits are zero
|
||||||
|
#endif
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Count leading zeros
|
||||||
|
|
||||||
|
This function counts the number of leading zeros of a data value.
|
||||||
|
|
||||||
|
\param [in] value Value to count the leading zeros
|
||||||
|
\return number of leading zeros in value
|
||||||
|
*/
|
||||||
|
#define __CLZ __builtin_clz
|
||||||
|
|
||||||
|
|
||||||
|
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive LDR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (8 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (16 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STR Exclusive (32 bit)
|
||||||
|
|
||||||
|
This function executes a exclusive STR instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
\return 0 Function succeeded
|
||||||
|
\return 1 Function failed
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Remove the exclusive lock
|
||||||
|
|
||||||
|
This function removes the exclusive lock which is created by LDREX.
|
||||||
|
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
||||||
|
{
|
||||||
|
__ASM volatile ("clrex" ::: "memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Signed Saturate
|
||||||
|
|
||||||
|
This function saturates a signed value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (1..32)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __SSAT(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Unsigned Saturate
|
||||||
|
|
||||||
|
This function saturates an unsigned value.
|
||||||
|
|
||||||
|
\param [in] value Value to be saturated
|
||||||
|
\param [in] sat Bit position to saturate to (0..31)
|
||||||
|
\return Saturated value
|
||||||
|
*/
|
||||||
|
#define __USAT(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief Rotate Right with Extend (32 bit)
|
||||||
|
|
||||||
|
This function moves each bit of a bitstring right by one bit.
|
||||||
|
The carry input is shifted in at the left end of the bitstring.
|
||||||
|
|
||||||
|
\param [in] value Value to rotate
|
||||||
|
\return Rotated value
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint8_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint8_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint16_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||||
|
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
#else
|
||||||
|
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||||
|
accepted by assembler. So has to use following less efficient pattern.
|
||||||
|
*/
|
||||||
|
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||||
|
#endif
|
||||||
|
return ((uint16_t) result); /* Add explicit type cast here */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief LDRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] ptr Pointer to data
|
||||||
|
\return value of type uint32_t at (*ptr)
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (8 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (16 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** \brief STRT Unprivileged (32 bit)
|
||||||
|
|
||||||
|
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||||
|
|
||||||
|
\param [in] value Value to store
|
||||||
|
\param [in] ptr Pointer to location
|
||||||
|
*/
|
||||||
|
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||||
|
{
|
||||||
|
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/*
|
||||||
|
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||||
|
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||||
|
* Including the CMSIS ones.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||||
|
|
||||||
|
#endif /* __CORE_CMINSTR_H */
|
697
include/cmsis/core_cmSimd.h
Normal file
697
include/cmsis/core_cmSimd.h
Normal file
@ -0,0 +1,697 @@
|
|||||||
|
/**************************************************************************//**
|
||||||
|
* @file core_cmSimd.h
|
||||||
|
* @brief CMSIS Cortex-M SIMD Header File
|
||||||
|
* @version V4.10
|
||||||
|
* @date 18. March 2015
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
- 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.
|
||||||
|
- Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ )
|
||||||
|
#pragma system_include /* treat file as system include file for MISRA check */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __CORE_CMSIMD_H
|
||||||
|
#define __CORE_CMSIMD_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* Hardware Abstraction Layer
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* ################### Compiler specific Intrinsics ########################### */
|
||||||
|
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||||
|
Access to dedicated SIMD instructions
|
||||||
|
@{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||||
|
/* ARM armcc specific functions */
|
||||||
|
#define __SADD8 __sadd8
|
||||||
|
#define __QADD8 __qadd8
|
||||||
|
#define __SHADD8 __shadd8
|
||||||
|
#define __UADD8 __uadd8
|
||||||
|
#define __UQADD8 __uqadd8
|
||||||
|
#define __UHADD8 __uhadd8
|
||||||
|
#define __SSUB8 __ssub8
|
||||||
|
#define __QSUB8 __qsub8
|
||||||
|
#define __SHSUB8 __shsub8
|
||||||
|
#define __USUB8 __usub8
|
||||||
|
#define __UQSUB8 __uqsub8
|
||||||
|
#define __UHSUB8 __uhsub8
|
||||||
|
#define __SADD16 __sadd16
|
||||||
|
#define __QADD16 __qadd16
|
||||||
|
#define __SHADD16 __shadd16
|
||||||
|
#define __UADD16 __uadd16
|
||||||
|
#define __UQADD16 __uqadd16
|
||||||
|
#define __UHADD16 __uhadd16
|
||||||
|
#define __SSUB16 __ssub16
|
||||||
|
#define __QSUB16 __qsub16
|
||||||
|
#define __SHSUB16 __shsub16
|
||||||
|
#define __USUB16 __usub16
|
||||||
|
#define __UQSUB16 __uqsub16
|
||||||
|
#define __UHSUB16 __uhsub16
|
||||||
|
#define __SASX __sasx
|
||||||
|
#define __QASX __qasx
|
||||||
|
#define __SHASX __shasx
|
||||||
|
#define __UASX __uasx
|
||||||
|
#define __UQASX __uqasx
|
||||||
|
#define __UHASX __uhasx
|
||||||
|
#define __SSAX __ssax
|
||||||
|
#define __QSAX __qsax
|
||||||
|
#define __SHSAX __shsax
|
||||||
|
#define __USAX __usax
|
||||||
|
#define __UQSAX __uqsax
|
||||||
|
#define __UHSAX __uhsax
|
||||||
|
#define __USAD8 __usad8
|
||||||
|
#define __USADA8 __usada8
|
||||||
|
#define __SSAT16 __ssat16
|
||||||
|
#define __USAT16 __usat16
|
||||||
|
#define __UXTB16 __uxtb16
|
||||||
|
#define __UXTAB16 __uxtab16
|
||||||
|
#define __SXTB16 __sxtb16
|
||||||
|
#define __SXTAB16 __sxtab16
|
||||||
|
#define __SMUAD __smuad
|
||||||
|
#define __SMUADX __smuadx
|
||||||
|
#define __SMLAD __smlad
|
||||||
|
#define __SMLADX __smladx
|
||||||
|
#define __SMLALD __smlald
|
||||||
|
#define __SMLALDX __smlaldx
|
||||||
|
#define __SMUSD __smusd
|
||||||
|
#define __SMUSDX __smusdx
|
||||||
|
#define __SMLSD __smlsd
|
||||||
|
#define __SMLSDX __smlsdx
|
||||||
|
#define __SMLSLD __smlsld
|
||||||
|
#define __SMLSLDX __smlsldx
|
||||||
|
#define __SEL __sel
|
||||||
|
#define __QADD __qadd
|
||||||
|
#define __QSUB __qsub
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||||
|
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||||
|
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||||
|
|
||||||
|
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||||
|
((int64_t)(ARG3) << 32) ) >> 32))
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||||
|
/* GNU gcc specific functions */
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __SSAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __USAT16(ARG1,ARG2) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1); \
|
||||||
|
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
|
||||||
|
{
|
||||||
|
union llreg_u{
|
||||||
|
uint32_t w32[2];
|
||||||
|
uint64_t w64;
|
||||||
|
} llr;
|
||||||
|
llr.w64 = acc;
|
||||||
|
|
||||||
|
#ifndef __ARMEB__ // Little endian
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
|
||||||
|
#else // Big endian
|
||||||
|
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return(llr.w64);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||||
|
{
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||||
|
({ \
|
||||||
|
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||||
|
if (ARG3 == 0) \
|
||||||
|
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||||
|
else \
|
||||||
|
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||||
|
__RES; \
|
||||||
|
})
|
||||||
|
|
||||||
|
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||||
|
{
|
||||||
|
int32_t result;
|
||||||
|
|
||||||
|
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||||
|
/* IAR iccarm specific functions */
|
||||||
|
#include <cmsis_iar.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||||
|
/* TI CCS specific functions */
|
||||||
|
#include <cmsis_ccs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||||
|
/* TASKING carm specific functions */
|
||||||
|
/* not yet supported */
|
||||||
|
|
||||||
|
|
||||||
|
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||||
|
/* Cosmic specific functions */
|
||||||
|
#include <cmsis_csm.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __CORE_CMSIMD_H */
|
44
include/stm-periph/stm32-gpio-macros.h
Normal file
44
include/stm-periph/stm32-gpio-macros.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* Reflow Oven Controller
|
||||||
|
*
|
||||||
|
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
|
||||||
|
*
|
||||||
|
* This file is part of the Reflow Oven Controller Project.
|
||||||
|
*
|
||||||
|
* The reflow oven controller is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* GDSII-Converter is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with the reflow oven controller project.
|
||||||
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STM32GPIOMACROS_H__
|
||||||
|
#define __STM32GPIOMACROS_H__
|
||||||
|
|
||||||
|
#define MODER_DELETE(pin) ~(0x3U << ((pin) * 2))
|
||||||
|
#define PUPDR_DELETE(pin) ~(0x3U << ((pin) * 2))
|
||||||
|
#define OUTPUT(pin) (0x01U << ((pin) * 2))
|
||||||
|
#define PULLUP(pin) (0x1U << ((pin)* 2))
|
||||||
|
#define PULLDOWN(pin) (0x2U << ((pin)* 2))
|
||||||
|
#define ALTFUNC(pin) ((0x2) << ((pin) * 2))
|
||||||
|
#define PINMASK(pin) ((0x3) << ((pin) * 2))
|
||||||
|
#define SETAF(PORT,PIN,AF) PORT->AFR[((PIN) < 8 ? 0 : 1)] |= (AF) << (((PIN) < 8 ? (PIN) : ((PIN) - 8)) * 4)
|
||||||
|
#define ANALOG(pin) (0x03 << ((pin) * 2))
|
||||||
|
#define OTYP_OPENDRAIN(pin) (0x1U << (pin))
|
||||||
|
|
||||||
|
#define BITMASK_TO_BITNO(x) (x&0x1?0:x&0x2?1:x&0x4?2:x&0x8?3: \
|
||||||
|
x&0x10?4:x&0x20?5:x&0x40?6:x&0x80?7: \
|
||||||
|
x&0x100?8:x&0x200?9:x&0x400?10:x&0x800?11: \
|
||||||
|
x&0x1000?12:x&0x2000?13:x&0x4000?14:x&0x8000?15: \
|
||||||
|
x&0x10000?16:x&0x20000?17:x&0x40000?18:x&0x80000?19: \
|
||||||
|
x&0x100000?20:x&0x200000?21:x&0x400000?22:x&0x800000?23: \
|
||||||
|
x&0x1000000?24:x&0x2000000?25:x&0x4000000?26:x&0x8000000?27: \
|
||||||
|
x&0x10000000?28:x&0x20000000?29:x&0x40000000?30:x&0x80000000?31:32)
|
||||||
|
|
||||||
|
#endif /* __STM32GPIOMACROS_H__ */
|
3157
include/stm32f030x6.h
Normal file
3157
include/stm32f030x6.h
Normal file
File diff suppressed because it is too large
Load Diff
244
include/stm32f0xx.h
Normal file
244
include/stm32f0xx.h
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file stm32f0xx.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.2.2
|
||||||
|
* @date 26-June-2015
|
||||||
|
* @brief CMSIS STM32F0xx Device Peripheral Access Layer Header File.
|
||||||
|
*
|
||||||
|
* The file is the unique include file that the application programmer
|
||||||
|
* is using in the C source code, usually in main.c. This file contains:
|
||||||
|
* - Configuration section that allows to select:
|
||||||
|
* - The STM32F0xx device used in the target application
|
||||||
|
* - To use or not the peripheral’s drivers in application code(i.e.
|
||||||
|
* code will be based on direct access to peripheral’s registers
|
||||||
|
* rather than drivers API), this option is controlled by
|
||||||
|
* "#define USE_HAL_DRIVER"
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT(c) 2015 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 stm32f0xx
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __STM32F0xx_H
|
||||||
|
#define __STM32F0xx_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/** @addtogroup Library_configuration_section
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief STM32 Family
|
||||||
|
*/
|
||||||
|
#if !defined (STM32F0)
|
||||||
|
#define STM32F0
|
||||||
|
#endif /* STM32F0 */
|
||||||
|
|
||||||
|
/* Uncomment the line below according to the target STM32 device used in your
|
||||||
|
application
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined (STM32F030x6) && !defined (STM32F030x8) && \
|
||||||
|
!defined (STM32F031x6) && !defined (STM32F038xx) && \
|
||||||
|
!defined (STM32F042x6) && !defined (STM32F048xx) && !defined (STM32F070x6) && \
|
||||||
|
!defined (STM32F051x8) && !defined (STM32F058xx) && \
|
||||||
|
!defined (STM32F071xB) && !defined (STM32F072xB) && !defined (STM32F078xx) && !defined (STM32F070xB) && \
|
||||||
|
!defined (STM32F091xC) && !defined (STM32F098xx) && !defined (STM32F030xC)
|
||||||
|
/* #define STM32F030x6 */ /*!< STM32F030x4, STM32F030x6 Devices (STM32F030xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */
|
||||||
|
/* #define STM32F030x8 */ /*!< STM32F030x8 Devices (STM32F030xx microcontrollers where the Flash memory is 64 Kbytes) */
|
||||||
|
/* #define STM32F031x6 */ /*!< STM32F031x4, STM32F031x6 Devices (STM32F031xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */
|
||||||
|
/* #define STM32F038xx */ /*!< STM32F038xx Devices (STM32F038xx microcontrollers where the Flash memory is 32 Kbytes) */
|
||||||
|
/* #define STM32F042x6 */ /*!< STM32F042x4, STM32F042x6 Devices (STM32F042xx microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */
|
||||||
|
/* #define STM32F048x6 */ /*!< STM32F048xx Devices (STM32F042xx microcontrollers where the Flash memory is 32 Kbytes) */
|
||||||
|
/* #define STM32F051x8 */ /*!< STM32F051x4, STM32F051x6, STM32F051x8 Devices (STM32F051xx microcontrollers where the Flash memory ranges between 16 and 64 Kbytes) */
|
||||||
|
/* #define STM32F058xx */ /*!< STM32F058xx Devices (STM32F058xx microcontrollers where the Flash memory is 64 Kbytes) */
|
||||||
|
/* #define STM32F070x6 */ /*!< STM32F070x6 Devices (STM32F070x6 microcontrollers where the Flash memory ranges between 16 and 32 Kbytes) */
|
||||||
|
/* #define STM32F070xB */ /*!< STM32F070xB Devices (STM32F070xB microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */
|
||||||
|
/* #define STM32F071xB */ /*!< STM32F071x8, STM32F071xB Devices (STM32F071xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */
|
||||||
|
/* #define STM32F072xB */ /*!< STM32F072x8, STM32F072xB Devices (STM32F072xx microcontrollers where the Flash memory ranges between 64 and 128 Kbytes) */
|
||||||
|
/* #define STM32F078xx */ /*!< STM32F078xx Devices (STM32F078xx microcontrollers where the Flash memory is 128 Kbytes) */
|
||||||
|
/* #define STM32F030xC */ /*!< STM32F030xC Devices (STM32F030xC microcontrollers where the Flash memory is 256 Kbytes) */
|
||||||
|
/* #define STM32F091xC */ /*!< STM32F091xC Devices (STM32F091xx microcontrollers where the Flash memory is 256 Kbytes) */
|
||||||
|
/* #define STM32F098xx */ /*!< STM32F098xx Devices (STM32F098xx microcontrollers where the Flash memory is 256 Kbytes) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Tip: To avoid modifying this file each time you need to switch between these
|
||||||
|
devices, you can define the device in your toolchain compiler preprocessor.
|
||||||
|
*/
|
||||||
|
#if !defined (USE_HAL_DRIVER)
|
||||||
|
/**
|
||||||
|
* @brief Comment the line below if you will not use the peripherals drivers.
|
||||||
|
In this case, these drivers will not be included and the application code will
|
||||||
|
be based on direct access to peripherals registers
|
||||||
|
*/
|
||||||
|
/*#define USE_HAL_DRIVER */
|
||||||
|
#endif /* USE_HAL_DRIVER */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief CMSIS Device version number V2.2.2
|
||||||
|
*/
|
||||||
|
#define __STM32F0xx_CMSIS_DEVICE_VERSION_MAIN (0x02) /*!< [31:24] main version */
|
||||||
|
#define __STM32F0xx_CMSIS_DEVICE_VERSION_SUB1 (0x02) /*!< [23:16] sub1 version */
|
||||||
|
#define __STM32F0xx_CMSIS_DEVICE_VERSION_SUB2 (0x02) /*!< [15:8] sub2 version */
|
||||||
|
#define __STM32F0xx_CMSIS_DEVICE_VERSION_RC (0x00) /*!< [7:0] release candidate */
|
||||||
|
#define __STM32F0xx_CMSIS_DEVICE_VERSION ((__CMSIS_DEVICE_VERSION_MAIN << 24)\
|
||||||
|
|(__CMSIS_DEVICE_HAL_VERSION_SUB1 << 16)\
|
||||||
|
|(__CMSIS_DEVICE_HAL_VERSION_SUB2 << 8 )\
|
||||||
|
|(__CMSIS_DEVICE_HAL_VERSION_RC))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup Device_Included
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(STM32F030x6)
|
||||||
|
#include "stm32f030x6.h"
|
||||||
|
#elif defined(STM32F030x8)
|
||||||
|
#include "stm32f030x8.h"
|
||||||
|
#elif defined(STM32F031x6)
|
||||||
|
#include "stm32f031x6.h"
|
||||||
|
#elif defined(STM32F038xx)
|
||||||
|
#include "stm32f038xx.h"
|
||||||
|
#elif defined(STM32F042x6)
|
||||||
|
#include "stm32f042x6.h"
|
||||||
|
#elif defined(STM32F048xx)
|
||||||
|
#include "stm32f048xx.h"
|
||||||
|
#elif defined(STM32F051x8)
|
||||||
|
#include "stm32f051x8.h"
|
||||||
|
#elif defined(STM32F058xx)
|
||||||
|
#include "stm32f058xx.h"
|
||||||
|
#elif defined(STM32F070x6)
|
||||||
|
#include "stm32f070x6.h"
|
||||||
|
#elif defined(STM32F070xB)
|
||||||
|
#include "stm32f070xb.h"
|
||||||
|
#elif defined(STM32F071xB)
|
||||||
|
#include "stm32f071xb.h"
|
||||||
|
#elif defined(STM32F072xB)
|
||||||
|
#include "stm32f072xb.h"
|
||||||
|
#elif defined(STM32F078xx)
|
||||||
|
#include "stm32f078xx.h"
|
||||||
|
#elif defined(STM32F091xC)
|
||||||
|
#include "stm32f091xc.h"
|
||||||
|
#elif defined(STM32F098xx)
|
||||||
|
#include "stm32f098xx.h"
|
||||||
|
#elif defined(STM32F030xC)
|
||||||
|
#include "stm32f030xc.h"
|
||||||
|
#else
|
||||||
|
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup Exported_types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RESET = 0,
|
||||||
|
SET = !RESET
|
||||||
|
} FlagStatus, ITStatus;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DISABLE = 0,
|
||||||
|
ENABLE = !DISABLE
|
||||||
|
} FunctionalState;
|
||||||
|
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ERROR = 0,
|
||||||
|
SUCCESS = !ERROR
|
||||||
|
} ErrorStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup Exported_macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
|
||||||
|
|
||||||
|
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
|
||||||
|
|
||||||
|
#define READ_BIT(REG, BIT) ((REG) & (BIT))
|
||||||
|
|
||||||
|
#define CLEAR_REG(REG) ((REG) = (0x0))
|
||||||
|
|
||||||
|
#define WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||||
|
|
||||||
|
#define READ_REG(REG) ((REG))
|
||||||
|
|
||||||
|
#define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined (USE_HAL_DRIVER)
|
||||||
|
#include "stm32f0xx_hal.h"
|
||||||
|
#endif /* USE_HAL_DRIVER */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* __STM32F0xx_H */
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
121
include/system_stm32f0xx.h
Normal file
121
include/system_stm32f0xx.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file system_stm32f0xx.h
|
||||||
|
* @author MCD Application Team
|
||||||
|
* @version V2.2.2
|
||||||
|
* @date 26-June-2015
|
||||||
|
* @brief CMSIS Cortex-M0 Device System Source File for STM32F0xx devices.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>© COPYRIGHT(c) 2015 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 stm32f0xx_system
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define to prevent recursive inclusion
|
||||||
|
*/
|
||||||
|
#ifndef __SYSTEM_STM32F0XX_H
|
||||||
|
#define __SYSTEM_STM32F0XX_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** @addtogroup STM32F0xx_System_Includes
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/** @addtogroup STM32F0xx_System_Exported_types
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/* This variable is updated in three ways:
|
||||||
|
1) by calling CMSIS function SystemCoreClockUpdate()
|
||||||
|
3) by calling HAL API function HAL_RCC_GetHCLKFreq()
|
||||||
|
3) by calling HAL API function HAL_RCC_ClockConfig()
|
||||||
|
Note: If you use this function to configure the system clock; then there
|
||||||
|
is no need to call the 2 first functions listed above, since SystemCoreClock
|
||||||
|
variable is updated automatically.
|
||||||
|
*/
|
||||||
|
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F0xx_System_Exported_Constants
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F0xx_System_Exported_Macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @addtogroup STM32F0xx_System_Exported_Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void SystemInit(void);
|
||||||
|
extern void SystemCoreClockUpdate(void);
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*__SYSTEM_STM32F0XX_H */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
9
include/systick.h
Normal file
9
include/systick.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef _SYSTICK_H_
|
||||||
|
#define _SYSTICK_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void systick_wait_ms(uint32_t ms);
|
||||||
|
uint32_t systick_get_global_tick(void);
|
||||||
|
|
||||||
|
#endif /* _SYSTICK_H_ */
|
58
main.c
Normal file
58
main.c
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#include <stm32f0xx.h>
|
||||||
|
#include <stm-periph/stm32-gpio-macros.h>
|
||||||
|
#include <systick.h>
|
||||||
|
|
||||||
|
static void setup_pins(void)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
RCC->AHBENR |= RCC_AHBENR_GPIOAEN | RCC_AHBENR_GPIOBEN;
|
||||||
|
|
||||||
|
tmp = GPIOA->MODER;
|
||||||
|
|
||||||
|
/* Reset all used port pins */
|
||||||
|
tmp &= MODER_DELETE(0) & MODER_DELETE(1) & MODER_DELETE(2) & MODER_DELETE(3) & \
|
||||||
|
MODER_DELETE(4) & MODER_DELETE(5) & MODER_DELETE(6) & MODER_DELETE(7) & \
|
||||||
|
MODER_DELETE(8) & MODER_DELETE(9) & MODER_DELETE(10);
|
||||||
|
|
||||||
|
/* Analog ports for POTIs */
|
||||||
|
tmp |= ANALOG(0) | ANALOG(1) | ANALOG(4);
|
||||||
|
|
||||||
|
/* Setup USART1 RX/TX (AF1) */
|
||||||
|
tmp |= ALTFUNC(2) | ALTFUNC(3);
|
||||||
|
SETAF(GPIOA, 2, 1);
|
||||||
|
SETAF(GPIOA, 3, 1);
|
||||||
|
|
||||||
|
/* LED enables for Potentiometers */
|
||||||
|
tmp |= OUTPUT(5) | OUTPUT(6) | OUTPUT(7);
|
||||||
|
GPIOA->ODR &= ~((1 << 5) | (1 << 6) | (1 << 7));
|
||||||
|
|
||||||
|
/* Setup I2C pins (AF4) */
|
||||||
|
tmp |= ALTFUNC(9) | ALTFUNC(10);
|
||||||
|
SETAF(GPIOA, 9, 4);
|
||||||
|
SETAF(GPIOA, 10, 4);
|
||||||
|
|
||||||
|
/* Set I2C Pins to open drain. Others are push pull */
|
||||||
|
GPIOA->OTYPER = OTYP_OPENDRAIN(9) | OTYP_OPENDRAIN(10);
|
||||||
|
|
||||||
|
/* Write changes to GPIOA mode register */
|
||||||
|
GPIOA->MODER = tmp;
|
||||||
|
|
||||||
|
/* PB1 Input with pullup */
|
||||||
|
GPIOB->MODER &= MODER_DELETE(1);
|
||||||
|
GPIOB->PUPDR = PULLUP(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
setup_pins();
|
||||||
|
SysTick_Config(48000000UL/1000);
|
||||||
|
|
||||||
|
GPIOA->ODR |= (1<<5) | (1<<7);
|
||||||
|
|
||||||
|
/* Blink the LEDs */
|
||||||
|
while (1) {
|
||||||
|
systick_wait_ms(250);
|
||||||
|
GPIOA->ODR ^= (1 << 5) | (1 << 6) | (1 << 7);
|
||||||
|
}
|
||||||
|
}
|
104
setup/system_init.c
Normal file
104
setup/system_init.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <stm32f0xx.h>
|
||||||
|
|
||||||
|
|
||||||
|
static void __init_default_clocks(void)
|
||||||
|
{
|
||||||
|
/* Reset the RCC clock configuration to the default reset state ------------*/
|
||||||
|
/* Set HSION bit */
|
||||||
|
RCC->CR |= (uint32_t)0x00000001;
|
||||||
|
|
||||||
|
#if defined (STM32F051x8) || defined (STM32F058x8)
|
||||||
|
/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE and MCOSEL[2:0] bits */
|
||||||
|
RCC->CFGR &= (uint32_t)0xF8FFB80C;
|
||||||
|
#else
|
||||||
|
/* Reset SW[1:0], HPRE[3:0], PPRE[2:0], ADCPRE, MCOSEL[2:0], MCOPRE[2:0] and PLLNODIV bits */
|
||||||
|
RCC->CFGR &= (uint32_t)0x08FFB80C;
|
||||||
|
#endif /* STM32F051x8 or STM32F058x8 */
|
||||||
|
|
||||||
|
/* Reset HSEON, CSSON and PLLON bits */
|
||||||
|
RCC->CR &= (uint32_t)0xFEF6FFFF;
|
||||||
|
|
||||||
|
/* Reset HSEBYP bit */
|
||||||
|
RCC->CR &= (uint32_t)0xFFFBFFFF;
|
||||||
|
|
||||||
|
/* Reset PLLSRC, PLLXTPRE and PLLMUL[3:0] bits */
|
||||||
|
RCC->CFGR &= (uint32_t)0xFFC0FFFF;
|
||||||
|
|
||||||
|
/* Reset PREDIV[3:0] bits */
|
||||||
|
RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
|
||||||
|
|
||||||
|
#if defined (STM32F072xB) || defined (STM32F078xx)
|
||||||
|
/* Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFCFE2C;
|
||||||
|
#elif defined (STM32F071xB)
|
||||||
|
/* Reset USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFFCEAC;
|
||||||
|
#elif defined (STM32F091xC) || defined (STM32F098xx)
|
||||||
|
/* Reset USART3SW[1:0], USART2SW[1:0], USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFF0FEAC;
|
||||||
|
#elif defined (STM32F030x6) || defined (STM32F030x8) || defined (STM32F031x6) || defined (STM32F038xx) || defined (STM32F030xC)
|
||||||
|
/* Reset USART1SW[1:0], I2C1SW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFFFEEC;
|
||||||
|
#elif defined (STM32F051x8) || defined (STM32F058xx)
|
||||||
|
/* Reset USART1SW[1:0], I2C1SW, CECSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFFFEAC;
|
||||||
|
#elif defined (STM32F042x6) || defined (STM32F048xx)
|
||||||
|
/* Reset USART1SW[1:0], I2C1SW, CECSW, USBSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFFFE2C;
|
||||||
|
#elif defined (STM32F070x6) || defined (STM32F070xB)
|
||||||
|
/* Reset USART1SW[1:0], I2C1SW, USBSW and ADCSW bits */
|
||||||
|
RCC->CFGR3 &= (uint32_t)0xFFFFFE6C;
|
||||||
|
/* Set default USB clock to PLLCLK, since there is no HSI48 */
|
||||||
|
RCC->CFGR3 |= (uint32_t)0x00000080;
|
||||||
|
#else
|
||||||
|
#warning "No target selected"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Reset HSI14 bit */
|
||||||
|
RCC->CR2 &= (uint32_t)0xFFFFFFFE;
|
||||||
|
|
||||||
|
/* Disable all interrupts */
|
||||||
|
RCC->CIR = 0x00000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __setup_clocks(void)
|
||||||
|
{
|
||||||
|
uint32_t tmp;
|
||||||
|
|
||||||
|
/* Switch PLL source to HSE OSC */
|
||||||
|
RCC->CFGR |= RCC_CFGR_PLLSRC;
|
||||||
|
|
||||||
|
/* Divide HSE by 2 to match HSI */
|
||||||
|
RCC->CFGR2 = 0x00000001;
|
||||||
|
|
||||||
|
/* Enable HSE and wait for it to become ready */
|
||||||
|
RCC->CR |= RCC_CR_HSEON;
|
||||||
|
|
||||||
|
/* Wait for HSE to be ready */
|
||||||
|
while (!(RCC->CR & RCC_CR_HSERDY));
|
||||||
|
|
||||||
|
/* Set PLL multiplication to 12 (4 MHz * 12 = 48 MHz SysClk) */
|
||||||
|
RCC->CFGR |= RCC_CFGR_PLLMUL_3 | RCC_CFGR_PLLMUL_1;
|
||||||
|
|
||||||
|
/* HSI Already running. Switch on PLL */
|
||||||
|
RCC->CR |= RCC_CR_PLLON;
|
||||||
|
|
||||||
|
/* Wait for PLL to be ready */
|
||||||
|
while (!(RCC->CR & RCC_CR_PLLRDY));
|
||||||
|
|
||||||
|
/* Switch System Clock to PLL */
|
||||||
|
tmp = RCC->CFGR;
|
||||||
|
tmp &= ~0x3;
|
||||||
|
tmp |= RCC_CFGR_SW_1;
|
||||||
|
RCC->CFGR = tmp;
|
||||||
|
|
||||||
|
/* Turn off HSI */
|
||||||
|
RCC->CR &= ~RCC_CR_HSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __system_init(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
__init_default_clocks();
|
||||||
|
__setup_clocks();
|
||||||
|
}
|
203
startup/startup_stm32f0xx.c
Normal file
203
startup/startup_stm32f0xx.c
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* STM32F030 Linkerscript
|
||||||
|
* Copyright (C) 2019 Stefan Strobel <stefan.strobel@shimatta.net>
|
||||||
|
*
|
||||||
|
* This file is part of 'STM32F0 code template'.
|
||||||
|
*
|
||||||
|
* It is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 2 of the License.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this template. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* ------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* C++ library init */
|
||||||
|
# if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
extern void __libc_init_array(void);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Defines for weak default handlers */
|
||||||
|
#define WEAK __attribute__((weak))
|
||||||
|
#define ALIAS(func) __attribute__ ((weak, alias (#func)))
|
||||||
|
|
||||||
|
/* Define for section mapping */
|
||||||
|
#define SECTION(sec) __attribute__((section(sec)))
|
||||||
|
|
||||||
|
/* Handler prototypes */
|
||||||
|
#if defined(_cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Interrupt Defualt handler */
|
||||||
|
WEAK void __int_default_handler(void);
|
||||||
|
|
||||||
|
/* Core Interrupts */
|
||||||
|
void Reset_Handler(void);
|
||||||
|
void NMI_Handler(void) ALIAS(__int_default_handler);
|
||||||
|
void HardFault_Handler(void) ALIAS(__int_default_handler);
|
||||||
|
void SVCall_Handler(void) ALIAS(__int_default_handler);
|
||||||
|
void PendSV_Handler(void) ALIAS(__int_default_handler);
|
||||||
|
void SysTick_Handler(void) ALIAS(__int_default_handler);
|
||||||
|
|
||||||
|
/* Peripheral Interrupts (by default mapped onto Default Handler) */
|
||||||
|
void WWDG_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void PVD_VDDIO2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void RTC_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void FLASH_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void RCC_CRS_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void EXTI0_1_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void EXTI2_3_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void EXTI4_15_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TSC_IRWHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void DMA_CH1_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void DMA_CH2_3_DMA2_CH1_2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void DMA_CH4_5_6_7_DMA2_CH3_4_5_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void ADC_COMP_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM1_BRK_UP_TRG_COM_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM1_CC_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM3_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM6_DAC_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM7_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM14_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM15_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM16_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void TIM17_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void I2C1_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void I2C2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void SPI1_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void SPI2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void USART1_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void USART2_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void USART3_4_5_6_7_8_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void CEC_CAN_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
void USB_IRQHandler(void) ALIAS(__int_default_handler);
|
||||||
|
|
||||||
|
|
||||||
|
extern int main(void);
|
||||||
|
extern void __system_init(void);
|
||||||
|
|
||||||
|
extern void __ld_top_of_stack(void);
|
||||||
|
#if defined(_cplusplus)
|
||||||
|
extern "C" }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void (* const vector_table[])(void) SECTION(".vectors") = {
|
||||||
|
&__ld_top_of_stack,
|
||||||
|
/* Core Interrupts */
|
||||||
|
Reset_Handler,
|
||||||
|
NMI_Handler,
|
||||||
|
HardFault_Handler,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
SVCall_Handler,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
PendSV_Handler,
|
||||||
|
SysTick_Handler,
|
||||||
|
/* Peripheral Interrupts */
|
||||||
|
WWDG_IRQHandler,
|
||||||
|
PVD_VDDIO2_IRQHandler,
|
||||||
|
RTC_IRQHandler,
|
||||||
|
FLASH_IRQHandler,
|
||||||
|
RCC_CRS_IRQHandler,
|
||||||
|
EXTI0_1_IRQHandler,
|
||||||
|
EXTI2_3_IRQHandler,
|
||||||
|
EXTI4_15_IRQHandler,
|
||||||
|
TSC_IRWHandler,
|
||||||
|
DMA_CH1_IRQHandler,
|
||||||
|
DMA_CH2_3_DMA2_CH1_2_IRQHandler,
|
||||||
|
DMA_CH4_5_6_7_DMA2_CH3_4_5_IRQHandler,
|
||||||
|
ADC_COMP_IRQHandler,
|
||||||
|
TIM1_BRK_UP_TRG_COM_IRQHandler,
|
||||||
|
TIM1_CC_IRQHandler,
|
||||||
|
TIM2_IRQHandler,
|
||||||
|
TIM3_IRQHandler,
|
||||||
|
TIM6_DAC_IRQHandler,
|
||||||
|
TIM7_IRQHandler,
|
||||||
|
TIM14_IRQHandler,
|
||||||
|
TIM15_IRQHandler,
|
||||||
|
TIM16_IRQHandler,
|
||||||
|
TIM17_IRQHandler,
|
||||||
|
I2C1_IRQHandler,
|
||||||
|
I2C2_IRQHandler,
|
||||||
|
SPI1_IRQHandler,
|
||||||
|
SPI2_IRQHandler,
|
||||||
|
USART1_IRQHandler,
|
||||||
|
USART2_IRQHandler,
|
||||||
|
USART3_4_5_6_7_8_IRQHandler,
|
||||||
|
CEC_CAN_IRQHandler,
|
||||||
|
USB_IRQHandler,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init_section(unsigned int *src_start, unsigned int *dest_start, unsigned int *dest_end) {
|
||||||
|
unsigned int *get, *put;
|
||||||
|
|
||||||
|
put = dest_start;
|
||||||
|
get = src_start;
|
||||||
|
|
||||||
|
while ((unsigned int)put < (unsigned int)dest_end) {
|
||||||
|
*(put++) = *(get++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __fill_zero(unsigned int *start, unsigned int *end) {
|
||||||
|
while ((unsigned int) start < (unsigned int)end) {
|
||||||
|
*(start++) = 0x00000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern unsigned int __ld_load_data;
|
||||||
|
extern unsigned int __ld_sitcm;
|
||||||
|
extern unsigned int __ld_eitcm;
|
||||||
|
extern unsigned int __ld_sdtcm;
|
||||||
|
extern unsigned int __ld_edtcm;
|
||||||
|
extern unsigned int __ld_sdata;
|
||||||
|
extern unsigned int __ld_edata;
|
||||||
|
extern unsigned int __ld_sbss;
|
||||||
|
extern unsigned int __ld_ebss;
|
||||||
|
extern unsigned int __ld_sheap;
|
||||||
|
extern unsigned int __ld_eheap;
|
||||||
|
|
||||||
|
void Reset_Handler(void) {
|
||||||
|
/* Stack is already initilized by hardware */
|
||||||
|
|
||||||
|
/* Copy .data section */
|
||||||
|
__init_section(&__ld_load_data, &__ld_sdata, &__ld_edata);
|
||||||
|
/* Fill bss with zero */
|
||||||
|
__fill_zero(&__ld_sbss, &__ld_ebss);
|
||||||
|
/* Fill Heap with zero */
|
||||||
|
__fill_zero(&__ld_sheap, &__ld_eheap);
|
||||||
|
/* Set clocks, waitstates, ART operation etc. */
|
||||||
|
__system_init();
|
||||||
|
|
||||||
|
/* C++ init function */
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
__libc_init_array();
|
||||||
|
#endif
|
||||||
|
/* Call main */
|
||||||
|
main();
|
||||||
|
|
||||||
|
/* Catch return from main() */
|
||||||
|
while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
WEAK void __int_default_handler(void)
|
||||||
|
{
|
||||||
|
while(1);
|
||||||
|
}
|
133
startup/stm32f030.ld
Normal file
133
startup/stm32f030.ld
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* STM32F030 Linkerscript
|
||||||
|
* Copyright (C) 2019 Stefan Strobel <stefan.strobel@shimatta.net>
|
||||||
|
*
|
||||||
|
* This file is part of 'STM32F0 code template'.
|
||||||
|
*
|
||||||
|
* It is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, version 2 of the License.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this template. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* --------------------------------------------------------------------
|
||||||
|
* FLASH: 16K
|
||||||
|
* RAM: 4K
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* USER PARAMETERS */
|
||||||
|
__ld_stack_size = 0x0400;
|
||||||
|
__ld_heap_size = 0x0000; /* No heap! */
|
||||||
|
|
||||||
|
/* END OF USER PARAMETERS */
|
||||||
|
ENTRY(Reset_Handler)
|
||||||
|
__ld_top_of_stack = 0x20001000; /* One byte above the end of the SRAM. Stack is pre-decrewmenting, so this is okay */
|
||||||
|
|
||||||
|
|
||||||
|
/* Available memory areas */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH (xr) : ORIGIN = 0x08000000, LENGTH = 16K
|
||||||
|
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.vectors : ALIGN(4)
|
||||||
|
{
|
||||||
|
KEEP(*(.vectors))
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH
|
||||||
|
|
||||||
|
.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.text) /* .text sections (code) */
|
||||||
|
*(.text*) /* .text* sections (code) */
|
||||||
|
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||||
|
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||||
|
*(.glue_7) /* glue arm to thumb code */
|
||||||
|
*(.glue_7t) /* glue thumb to arm code */
|
||||||
|
*(.eh_frame)
|
||||||
|
KEEP(*(.init)) /* Constructors */
|
||||||
|
KEEP(*(.fini)) /* Destructors */
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
.ARM.extab : ALIGN(4)
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
.ARM : ALIGN(4)
|
||||||
|
{
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
/* Constructor/Destructor tables */
|
||||||
|
.preinit_array : ALIGN(4)
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP (*(.preinit_array*))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
.init_array : ALIGN(4)
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP (*(SORT(.init_array.*)))
|
||||||
|
KEEP (*(.init_array*))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
.fini_array : ALIGN(4)
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
KEEP (*(.fini_array*))
|
||||||
|
KEEP (*(SORT(.fini_array.*)))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >FLASH =0xFF
|
||||||
|
|
||||||
|
/* Initialized Data */
|
||||||
|
__ld_load_data = LOADADDR(.data);
|
||||||
|
.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
__ld_sdata = .;
|
||||||
|
*(.data)
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ld_edata = .;
|
||||||
|
} >RAM AT> FLASH
|
||||||
|
|
||||||
|
/* Uninitialized static data */
|
||||||
|
.bss : ALIGN(4)
|
||||||
|
{
|
||||||
|
__ld_sbss = .;
|
||||||
|
*(.bss)
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__ld_ebss = .;
|
||||||
|
} >RAM
|
||||||
|
|
||||||
|
.heap_stack (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
__ld_sheap = .;
|
||||||
|
. = . + __ld_heap_size;
|
||||||
|
__ld_eheap = .;
|
||||||
|
. = . + __ld_stack_size;
|
||||||
|
. = ALIGN(4);
|
||||||
|
} >RAM
|
||||||
|
}
|
||||||
|
|
22
systick.c
Normal file
22
systick.c
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <systick.h>
|
||||||
|
|
||||||
|
volatile uint32_t global_systick = 0;
|
||||||
|
volatile uint32_t systick_wait_counter;
|
||||||
|
|
||||||
|
void systick_wait_ms(uint32_t ms)
|
||||||
|
{
|
||||||
|
systick_wait_counter = ms;
|
||||||
|
|
||||||
|
while (systick_wait_counter > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t systick_get_global_tick(void)
|
||||||
|
{
|
||||||
|
return global_systick;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SysTick_Handler(void)
|
||||||
|
{
|
||||||
|
global_systick++;
|
||||||
|
systick_wait_counter--;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user