├── .gitignore ├── Makefile ├── README.md ├── blinky.c ├── libarm ├── stm32f4xx.rs ├── stm32f4xx_gpio.rs └── stm32f4xx_rcc.rs ├── main.rs ├── sys ├── inc │ ├── core │ │ ├── arm_common_tables.h │ │ ├── arm_math.h │ │ ├── core_cm0.h │ │ ├── core_cm3.h │ │ ├── core_cm4.h │ │ ├── core_cm4_simd.h │ │ ├── core_cmFunc.h │ │ └── core_cmInstr.h │ ├── stm32f4xx.h │ └── system_stm32f4xx.h ├── startup_stm32f4xx.s ├── stm32_flash.ld └── system_stm32f4xx.c ├── target.json └── zero ├── std_types.rs └── zero.rs /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | 4 | # Libraries 5 | *.lib 6 | *.a 7 | 8 | # Shared objects (inc. Windows DLLs) 9 | *.dll 10 | *.so 11 | *.so.* 12 | *.dylib 13 | 14 | # Executables 15 | *.exe 16 | *.out 17 | *.app 18 | *.elf 19 | *.hex 20 | *.bin 21 | 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Binaries will be generated with this name (.elf, .bin, .hex, etc) 2 | PROJ_NAME=blinky 3 | 4 | # Put your stlink folder here so make burn will work. 5 | STFLASH=st-flash 6 | RUSTC=rustc 7 | LLC=llc-3.6 8 | 9 | CC=arm-none-eabi-gcc 10 | AR=arm-none-eabi-ar 11 | OBJCOPY=arm-none-eabi-objcopy 12 | 13 | # Put your source files here (or *.c, etc) 14 | SRCS=sys/system_stm32f4xx.c 15 | 16 | # add startup file to build 17 | SRCS += sys/startup_stm32f4xx.s 18 | 19 | OBJS = $(SRCS:.c=.o) 20 | OBJS := $(OBJS:.s=.o) 21 | 22 | AFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 23 | 24 | CFLAGS = -g -O0 -Wall 25 | CFLAGS += -mlittle-endian $(AFLAGS) 26 | CFLAGS += -Isys/inc -Isys/inc/core 27 | 28 | LDFLAGS = -Tsys/stm32_flash.ld $(AFLAGS) 29 | 30 | .c.o: 31 | $(CC) $(CFLAGS) -c $< -o $@ 32 | 33 | .s.o: 34 | $(CC) $(CFLAGS) -c $< -o $@ 35 | 36 | .PHONY: proj 37 | 38 | all: proj 39 | 40 | proj: $(PROJ_NAME).hex $(PROJ_NAME).bin 41 | 42 | libcompiler-rt.a: $(OBJS) 43 | $(AR) rcs $@ $(OBJS) 44 | 45 | blinky.elf: main.rs libcompiler-rt.a 46 | $(RUSTC) --target target.json -A non_camel_case_types -A dead_code -A non_snake_case main.rs -C link-args="$(LDFLAGS)" -L. -o $@ -Z print-link-args 47 | 48 | $(PROJ_NAME).hex: blinky.elf 49 | $(OBJCOPY) -O ihex $(PROJ_NAME).elf $(PROJ_NAME).hex 50 | 51 | $(PROJ_NAME).bin: blinky.elf 52 | $(OBJCOPY) -O binary $(PROJ_NAME).elf $(PROJ_NAME).bin 53 | 54 | clean: 55 | rm -f *.o *.a sys/*.o $(PROJ_NAME).elf $(PROJ_NAME).hex $(PROJ_NAME).bin 56 | 57 | burn: $(PROJ_NAME).bin 58 | $(STFLASH) write $(PROJ_NAME).bin 0x8000000 59 | 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | armboot 2 | ======= 3 | 4 | A testbed project used for porting the Rust language to bare metal STM32F4xx ARM microcontrollers. 5 | Tested on STM32F4DISCOVERY. 6 | 7 | The project resulted in patches to the [Rust compiler](https://github.com/rust-lang/llvm/pull/4 8 | ) and eventually to [LLVM](https://github.com/llvm-mirror/llvm/commit/af48fc4136b1fca9b0542bc858a3bddbf87dcc02 9 | ) to add support for segmented stacks to the platform. 10 | 11 | The current version supports only static memory allocation and no stack pointer safety checks. 12 | 13 | Requirements: 14 | ------------- 15 | * arm-none-eabi toolchain 16 | * llvm-3.6 (nightly) toolchain 17 | * rustc (requires Rust 1.0.0-alpha2) 18 | 19 | Compiling: 20 | ---------- 21 | 22 | Edit "Makefile" with the path to the rustc compiler and type "make". 23 | 24 | Upload the resulting binary (one of blinky.{elf, bin, hex}) on the target. 25 | 26 | Structure 27 | --------- 28 | * main.rs - sample program (blinks the red led of the STM32F4DISCOVERY board) 29 | * libarm/ - microcontroller related definitions 30 | * sys/ - bootstrap code (boot loader and system initialization) 31 | * zero/ - zero.rs and additional C stubs 32 | 33 | Credits 34 | ------- 35 | * The C source for the rust code: http://jeremyherbert.net/get/stm32f4_getting_started 36 | * The project structure and build script: https://github.com/rowol/stm32_discovery_arm_gcc 37 | * Rust zero.rs: https://github.com/pcwalton/zero.rs 38 | 39 | -------------------------------------------------------------------------------- /blinky.c: -------------------------------------------------------------------------------- 1 | //source: http://jeremyherbert.net/get/stm32f4_getting_started 2 | //Only for comparison, not used in the project build. 3 | 4 | #include "stm32f4xx_conf.h" 5 | 6 | void TIM2_IRQHandler(void) { 7 | // flash on update event 8 | if (TIM2->SR & TIM_SR_UIF) GPIOD->ODR ^= (1 << 13); 9 | 10 | TIM2->SR = 0x0; // reset the status register 11 | } 12 | 13 | int main(void) 14 | { 15 | RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN; // enable the clock to GPIOD 16 | RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // enable TIM2 clock 17 | 18 | GPIOD->MODER = (1 << 26); // set pin 13 to be general purpose output 19 | 20 | NVIC->ISER[0] |= 1<< (TIM2_IRQn); // enable the TIM2 IRQ 21 | 22 | TIM2->PSC = 0x0; // no prescaler, timer counts up in sync with the peripheral clock 23 | TIM2->DIER |= TIM_DIER_UIE; // enable update interrupt 24 | TIM2->ARR = 0x01; // count to 1 (autoreload value 1) 25 | TIM2->CR1 |= TIM_CR1_ARPE | TIM_CR1_CEN; // autoreload on, counter enabled 26 | TIM2->EGR = 1; // trigger update event to reload timer registers 27 | 28 | while (1); 29 | } 30 | 31 | -------------------------------------------------------------------------------- /libarm/stm32f4xx_gpio.rs: -------------------------------------------------------------------------------- 1 | use zero::std_types::*; 2 | 3 | /* STM32F4xx_StdPeriph_Driver 4 | */ 5 | 6 | /* GPIO 7 | */ 8 | 9 | /* Exported types ------------------------------------------------------------*/ 10 | macro_rules! IS_GPIO_ALL_PERIPH {($PERIPH:ident) => ((($PERIPH) == GPIOA) || 11 | (($PERIPH) == GPIOB) || 12 | (($PERIPH) == GPIOC) || 13 | (($PERIPH) == GPIOD) || 14 | (($PERIPH) == GPIOE) || 15 | (($PERIPH) == GPIOF) || 16 | (($PERIPH) == GPIOG) || 17 | (($PERIPH) == GPIOH) || 18 | (($PERIPH) == GPIOI));} 19 | 20 | /* 21 | * GPIO Configuration Mode enumeration 22 | */ 23 | pub type GPIOMode_TypeDef = c_uint; 24 | macro_rules! GPIO_Mode_IN {() => (0x00u32 as c_uint);} /*< GPIO Input Mode */ 25 | macro_rules! GPIO_Mode_OUT {() => (0x01u32 as c_uint);} /*< GPIO Output Mode */ 26 | macro_rules! GPIO_Mode_AF {() => (0x02u32 as c_uint);} /*< GPIO Alternate function Mode */ 27 | macro_rules! GPIO_Mode_AN {() => (0x03u32 as c_uint);} /*< GPIO Analog Mode */ 28 | 29 | macro_rules! IS_GPIO_MODE {($MODE:ident) => ((($MODE) == GPIO_Mode_IN!()) || (($MODE) == GPIO_Mode_OUT!()) || 30 | (($MODE) == GPIO_Mode_AF!())|| (($MODE) == GPIO_Mode_AN!()));} 31 | 32 | /* 33 | * GPIO Output type enumeration 34 | */ 35 | pub type GPIOOType_TypeDef = c_uint; 36 | macro_rules! GPIO_OType_PP {() => (0x00u32 as c_uint);} 37 | macro_rules! GPIO_OType_OD {() => (0x01u32 as c_uint);} 38 | macro_rules! IS_GPIO_OTYPE {($OTYPE:ident) => ((($OTYPE) == GPIO_OType_PP!()) || (($OTYPE) == GPIO_OType_OD!()));} 39 | 40 | 41 | /* 42 | * GPIO Output Maximum frequency enumeration 43 | */ 44 | pub type GPIOSpeed_TypeDef = c_uint; 45 | macro_rules! GPIO_Speed_2MHz {() => (0x00u32 as c_uint);} /*< Low speed */ 46 | macro_rules! GPIO_Speed_25MHz {() => (0x01u32 as c_uint);} /*< Medium speed */ 47 | macro_rules! GPIO_Speed_50MHz {() => (0x02u32 as c_uint);} /*< Fast speed */ 48 | macro_rules! GPIO_Speed_100MHz {() => (0x03u32 as c_uint);} /*< High speed on 30 pF (80 MHz Output max speed on 15 pF) */ 49 | macro_rules! IS_GPIO_SPEED {($SPEED:ident) => ((($SPEED) == GPIO_Speed_2MHz!()) || (($SPEED) == GPIO_Speed_25MHz!()) || 50 | (($SPEED) == GPIO_Speed_50MHz!())|| (($SPEED) == GPIO_Speed_100MHz!()));} 51 | 52 | /* 53 | * GPIO Configuration PullUp PullDown enumeration 54 | */ 55 | pub type GPIOPuPd_TypeDef = c_uint; 56 | macro_rules! GPIO_PuPd_NOPULL {() => (0x00u32 as c_uint);} 57 | macro_rules! GPIO_PuPd_UP {() => (0x01u32 as c_uint);} 58 | macro_rules! GPIO_PuPd_DOWN {() => (0x02u32 as c_uint);} 59 | macro_rules! IS_GPIO_PUPD {($PUPD:ident) => ((($PUPD) == GPIO_PuPd_NOPULL!()) || (($PUPD) == GPIO_PuPd_UP!()) || 60 | (($PUPD) == GPIO_PuPd_DOWN!()));} 61 | 62 | /* 63 | * GPIO Bit SET and Bit RESET enumeration 64 | */ 65 | pub type BitAction = c_uint; 66 | macro_rules! Bit_RESET {() => (0u32 as c_uint);} 67 | macro_rules! Bit_SET {() => (1u32 as c_uint);} 68 | macro_rules! IS_GPIO_BIT_ACTION {($ACTION:ident) => ((($ACTION) == Bit_RESET!()) || (($ACTION) == Bit_SET!()));} 69 | 70 | 71 | /* 72 | * GPIO Init structure definition 73 | */ 74 | pub struct GPIO_InitTypeDef { 75 | pub GPIO_Pin :uint32_t, /*< Specifies the GPIO pins to be configured. 76 | This parameter can be any value of GPIO_pins_define */ 77 | 78 | pub GPIO_Mode :GPIOMode_TypeDef, /*< Specifies the operating mode for the selected pins. 79 | This parameter can be a value of GPIOMode_TypeDef */ 80 | 81 | pub GPIO_Speed :GPIOSpeed_TypeDef, /*< Specifies the speed for the selected pins. 82 | This parameter can be a value of GPIOSpeed_TypeDef */ 83 | 84 | pub GPIO_OType :GPIOOType_TypeDef, /*< Specifies the operating output type for the selected pins. 85 | This parameter can be a value of GPIOOType_TypeDef */ 86 | 87 | pub GPIO_PuPd :GPIOPuPd_TypeDef /*< Specifies the operating Pull-up/Pull down for the selected pins. 88 | This parameter can be a value of GPIOPuPd_TypeDef */ 89 | } 90 | 91 | /* Exported constants --------------------------------------------------------*/ 92 | 93 | /* GPIO_Exported_Constants 94 | */ 95 | 96 | /* GPIO_pins_define 97 | */ 98 | macro_rules! GPIO_Pin_0 {() => (0x0001u16 as uint16_t);} /* Pin 0 selected */ 99 | macro_rules! GPIO_Pin_1 {() => (0x0002u16 as uint16_t);} /* Pin 1 selected */ 100 | macro_rules! GPIO_Pin_2 {() => (0x0004u16 as uint16_t);} /* Pin 2 selected */ 101 | macro_rules! GPIO_Pin_3 {() => (0x0008u16 as uint16_t);} /* Pin 3 selected */ 102 | macro_rules! GPIO_Pin_4 {() => (0x0010u16 as uint16_t);} /* Pin 4 selected */ 103 | macro_rules! GPIO_Pin_5 {() => (0x0020u16 as uint16_t);} /* Pin 5 selected */ 104 | macro_rules! GPIO_Pin_6 {() => (0x0040u16 as uint16_t);} /* Pin 6 selected */ 105 | macro_rules! GPIO_Pin_7 {() => (0x0080u16 as uint16_t);} /* Pin 7 selected */ 106 | macro_rules! GPIO_Pin_8 {() => (0x0100u16 as uint16_t);} /* Pin 8 selected */ 107 | macro_rules! GPIO_Pin_9 {() => (0x0200u16 as uint16_t);} /* Pin 9 selected */ 108 | macro_rules! GPIO_Pin_10 {() => (0x0400u16 as uint16_t);} /* Pin 10 selected */ 109 | macro_rules! GPIO_Pin_11 {() => (0x0800u16 as uint16_t);} /* Pin 11 selected */ 110 | macro_rules! GPIO_Pin_12 {() => (0x1000u16 as uint16_t);} /* Pin 12 selected */ 111 | macro_rules! GPIO_Pin_13 {() => (0x2000u16 as uint16_t);} /* Pin 13 selected */ 112 | macro_rules! GPIO_Pin_14 {() => (0x4000u16 as uint16_t);} /* Pin 14 selected */ 113 | macro_rules! GPIO_Pin_15 {() => (0x8000u16 as uint16_t);} /* Pin 15 selected */ 114 | macro_rules! GPIO_Pin_All {() => (0xFFFFu16 as uint16_t);} /* All pins selected */ 115 | 116 | macro_rules! IS_GPIO_PIN {($PIN:ident) => (((($PIN) & (0x00u16 as uint16_t)) == 0x00) && ((PIN) != (0x00u16 as uint16_t)));} 117 | macro_rules! IS_GET_GPIO_PIN {($PIN:ident) => ((($PIN) == GPIO_Pin_0!()) || 118 | (($PIN) == GPIO_Pin_1!()) || 119 | (($PIN) == GPIO_Pin_2!()) || 120 | (($PIN) == GPIO_Pin_3!()) || 121 | (($PIN) == GPIO_Pin_4!()) || 122 | (($PIN) == GPIO_Pin_5!()) || 123 | (($PIN) == GPIO_Pin_6!()) || 124 | (($PIN) == GPIO_Pin_7!()) || 125 | (($PIN) == GPIO_Pin_8!()) || 126 | (($PIN) == GPIO_Pin_9!()) || 127 | (($PIN) == GPIO_Pin_10!()) || 128 | (($PIN) == GPIO_Pin_11!()) || 129 | (($PIN) == GPIO_Pin_12!()) || 130 | (($PIN) == GPIO_Pin_13!()) || 131 | (($PIN) == GPIO_Pin_14!()) || 132 | (($PIN) == GPIO_Pin_15!()));} 133 | /* GPIO_Pin_sources 134 | */ 135 | macro_rules! GPIO_PinSource0 {() => (0x00u8 as uint8_t);} 136 | macro_rules! GPIO_PinSource1 {() => (0x01u8 as uint8_t);} 137 | macro_rules! GPIO_PinSource2 {() => (0x02u8 as uint8_t);} 138 | macro_rules! GPIO_PinSource3 {() => (0x03u8 as uint8_t);} 139 | macro_rules! GPIO_PinSource4 {() => (0x04u8 as uint8_t);} 140 | macro_rules! GPIO_PinSource5 {() => (0x05u8 as uint8_t);} 141 | macro_rules! GPIO_PinSource6 {() => (0x06u8 as uint8_t);} 142 | macro_rules! GPIO_PinSource7 {() => (0x07u8 as uint8_t);} 143 | macro_rules! GPIO_PinSource8 {() => (0x08u8 as uint8_t);} 144 | macro_rules! GPIO_PinSource9 {() => (0x09u8 as uint8_t);} 145 | macro_rules! GPIO_PinSource10 {() => (0x0Au8 as uint8_t);} 146 | macro_rules! GPIO_PinSource11 {() => (0x0Bu8 as uint8_t);} 147 | macro_rules! GPIO_PinSource12 {() => (0x0Cu8 as uint8_t);} 148 | macro_rules! GPIO_PinSource13 {() => (0x0Du8 as uint8_t);} 149 | macro_rules! GPIO_PinSource14 {() => (0x0Eu8 as uint8_t);} 150 | macro_rules! GPIO_PinSource15 {() => (0x0Fu8 as uint8_t);} 151 | 152 | macro_rules! IS_GPIO_PIN_SOURCE {($PINSOURCE:ident) => ((($PINSOURCE) == GPIO_PinSource0!()) || 153 | (($PINSOURCE) == GPIO_PinSource1!()) || 154 | (($PINSOURCE) == GPIO_PinSource2!()) || 155 | (($PINSOURCE) == GPIO_PinSource3!()) || 156 | (($PINSOURCE) == GPIO_PinSource4!()) || 157 | (($PINSOURCE) == GPIO_PinSource5!()) || 158 | (($PINSOURCE) == GPIO_PinSource6!()) || 159 | (($PINSOURCE) == GPIO_PinSource7!()) || 160 | (($PINSOURCE) == GPIO_PinSource8!()) || 161 | (($PINSOURCE) == GPIO_PinSource9!()) || 162 | (($PINSOURCE) == GPIO_PinSource10!()) || 163 | (($PINSOURCE) == GPIO_PinSource11!()) || 164 | (($PINSOURCE) == GPIO_PinSource12!()) || 165 | (($PINSOURCE) == GPIO_PinSource13!()) || 166 | (($PINSOURCE) == GPIO_PinSource14!()) || 167 | (($PINSOURCE) == GPIO_PinSource15!()));} 168 | /* GPIO_Alternat_function_selection_define 169 | */ 170 | /* 171 | * AF 0 selection 172 | */ 173 | macro_rules! GPIO_AF_RTC_50Hz {() => (0x00u8 as uint8_t);} /* RTC_50Hz Alternate Function mapping */ 174 | macro_rules! GPIO_AF_MCO {() => (0x00u8 as uint8_t);} /* MCO (MCO1 and MCO2) Alternate Function mapping */ 175 | macro_rules! GPIO_AF_TAMPER {() => (0x00u8 as uint8_t);} /* TAMPER (TAMPER_1 and TAMPER_2) Alternate Function mapping */ 176 | macro_rules! GPIO_AF_SWJ {() => (0x00u8 as uint8_t);} /* SWJ (SWD and JTAG) Alternate Function mapping */ 177 | macro_rules! GPIO_AF_TRACE {() => (0x00u8 as uint8_t);} /* TRACE Alternate Function mapping */ 178 | 179 | /* 180 | * AF 1 selection 181 | */ 182 | macro_rules! GPIO_AF_TIM1 {() => (0x01u8 as uint8_t);} /* TIM1 Alternate Function mapping */ 183 | macro_rules! GPIO_AF_TIM2 {() => (0x01u8 as uint8_t);} /* TIM2 Alternate Function mapping */ 184 | 185 | /* 186 | * AF 2 selection 187 | */ 188 | macro_rules! GPIO_AF_TIM3 {() => (0x02u8 as uint8_t);} /* TIM3 Alternate Function mapping */ 189 | macro_rules! GPIO_AF_TIM4 {() => (0x02u8 as uint8_t);} /* TIM4 Alternate Function mapping */ 190 | macro_rules! GPIO_AF_TIM5 {() => (0x02u8 as uint8_t);} /* TIM5 Alternate Function mapping */ 191 | 192 | /* 193 | * AF 3 selection 194 | */ 195 | macro_rules! GPIO_AF_TIM8 {() => (0x03u8 as uint8_t);} /* TIM8 Alternate Function mapping */ 196 | macro_rules! GPIO_AF_TIM9 {() => (0x03u8 as uint8_t);} /* TIM9 Alternate Function mapping */ 197 | macro_rules! GPIO_AF_TIM10 {() => (0x03u8 as uint8_t);} /* TIM10 Alternate Function mapping */ 198 | macro_rules! GPIO_AF_TIM11 {() => (0x03u8 as uint8_t);} /* TIM11 Alternate Function mapping */ 199 | 200 | /* 201 | * AF 4 selection 202 | */ 203 | macro_rules! GPIO_AF_I2C1 {() => (0x04u8 as uint8_t);} /* I2C1 Alternate Function mapping */ 204 | macro_rules! GPIO_AF_I2C2 {() => (0x04u8 as uint8_t);} /* I2C2 Alternate Function mapping */ 205 | macro_rules! GPIO_AF_I2C3 {() => (0x04u8 as uint8_t);} /* I2C3 Alternate Function mapping */ 206 | 207 | /* 208 | * AF 5 selection 209 | */ 210 | macro_rules! GPIO_AF_SPI1 {() => (0x05u8 as uint8_t);} /* SPI1 Alternate Function mapping */ 211 | macro_rules! GPIO_AF_SPI2 {() => (0x05u8 as uint8_t);} /* SPI2/I2S2 Alternate Function mapping */ 212 | 213 | /* 214 | * AF 6 selection 215 | */ 216 | macro_rules! GPIO_AF_SPI3 {() => (0x06u8 as uint8_t);} /* SPI3/I2S3 Alternate Function mapping */ 217 | 218 | /* 219 | * AF 7 selection 220 | */ 221 | macro_rules! GPIO_AF_USART1 {() => (0x07u8 as uint8_t);} /* USART1 Alternate Function mapping */ 222 | macro_rules! GPIO_AF_USART2 {() => (0x07u8 as uint8_t);} /* USART2 Alternate Function mapping */ 223 | macro_rules! GPIO_AF_USART3 {() => (0x07u8 as uint8_t);} /* USART3 Alternate Function mapping */ 224 | macro_rules! GPIO_AF_I2S3ext {() => (0x07u8 as uint8_t);} /* I2S3ext Alternate Function mapping */ 225 | 226 | /* 227 | * AF 8 selection 228 | */ 229 | macro_rules! GPIO_AF_UART4 {() => (0x08u8 as uint8_t);} /* UART4 Alternate Function mapping */ 230 | macro_rules! GPIO_AF_UART5 {() => (0x08u8 as uint8_t);} /* UART5 Alternate Function mapping */ 231 | macro_rules! GPIO_AF_USART6 {() => (0x08u8 as uint8_t);} /* USART6 Alternate Function mapping */ 232 | 233 | /* 234 | * AF 9 selection 235 | */ 236 | macro_rules! GPIO_AF_CAN1 {() => (0x09u8 as uint8_t);} /* CAN1 Alternate Function mapping */ 237 | macro_rules! GPIO_AF_CAN2 {() => (0x09u8 as uint8_t);} /* CAN2 Alternate Function mapping */ 238 | macro_rules! GPIO_AF_TIM12 {() => (0x09u8 as uint8_t);} /* TIM12 Alternate Function mapping */ 239 | macro_rules! GPIO_AF_TIM13 {() => (0x09u8 as uint8_t);} /* TIM13 Alternate Function mapping */ 240 | macro_rules! GPIO_AF_TIM14 {() => (0x09u8 as uint8_t);} /* TIM14 Alternate Function mapping */ 241 | 242 | /* 243 | * AF 10 selection 244 | */ 245 | macro_rules! GPIO_AF_OTG_FS {() => (0xAu8 as uint8_t);} /* OTG_FS Alternate Function mapping */ 246 | macro_rules! GPIO_AF_OTG_HS {() => (0xAu8 as uint8_t);} /* OTG_HS Alternate Function mapping */ 247 | 248 | /* 249 | * AF 11 selection 250 | */ 251 | macro_rules! GPIO_AF_ETH {() => (0x0Bu8 as uint8_t);} /* ETHERNET Alternate Function mapping */ 252 | 253 | /* 254 | * AF 12 selection 255 | */ 256 | macro_rules! GPIO_AF_FSMC {() => (0xCu8 as uint8_t);} /* FSMC Alternate Function mapping */ 257 | macro_rules! GPIO_AF_OTG_HS_FS {() => (0xCu8 as uint8_t);} /* OTG HS configured in FS, Alternate Function mapping */ 258 | macro_rules! GPIO_AF_SDIO {() => (0xCu8 as uint8_t);} /* SDIO Alternate Function mapping */ 259 | 260 | /* 261 | * AF 13 selection 262 | */ 263 | macro_rules! GPIO_AF_DCMI {() => (0x0Du8 as uint8_t);} /* DCMI Alternate Function mapping */ 264 | 265 | /* 266 | * AF 15 selection 267 | */ 268 | macro_rules! GPIO_AF_EVENTOUT {() => (0x0Fu8 as uint8_t);} /* EVENTOUT Alternate Function mapping */ 269 | 270 | macro_rules! IS_GPIO_AF {($AF:ident) => ((($AF) == GPIO_AF_RTC_50Hz!()) || (($AF) == GPIO_AF_TIM14!()) || 271 | (($AF) == GPIO_AF_MCO!()) || (($AF) == GPIO_AF_TAMPER!()) || 272 | (($AF) == GPIO_AF_SWJ!()) || (($AF) == GPIO_AF_TRACE!()) || 273 | (($AF) == GPIO_AF_TIM1!()) || (($AF) == GPIO_AF_TIM2!()) || 274 | (($AF) == GPIO_AF_TIM3!()) || (($AF) == GPIO_AF_TIM4!()) || 275 | (($AF) == GPIO_AF_TIM5!()) || (($AF) == GPIO_AF_TIM8!()) || 276 | (($AF) == GPIO_AF_I2C1!()) || (($AF) == GPIO_AF_I2C2!()) || 277 | (($AF) == GPIO_AF_I2C3!()) || (($AF) == GPIO_AF_SPI1!()) || 278 | (($AF) == GPIO_AF_SPI2!()) || (($AF) == GPIO_AF_TIM13!()) || 279 | (($AF) == GPIO_AF_SPI3!()) || (($AF) == GPIO_AF_TIM14!()) || 280 | (($AF) == GPIO_AF_USART1!()) || (($AF) == GPIO_AF_USART2!()) || 281 | (($AF) == GPIO_AF_USART3!()) || (($AF) == GPIO_AF_UART4!()) || 282 | (($AF) == GPIO_AF_UART5!()) || (($AF) == GPIO_AF_USART6!()) || 283 | (($AF) == GPIO_AF_CAN1!()) || (($AF) == GPIO_AF_CAN2!()) || 284 | (($AF) == GPIO_AF_OTG_FS!()) || (($AF) == GPIO_AF_OTG_HS!()) || 285 | (($AF) == GPIO_AF_ETH!()) || (($AF) == GPIO_AF_FSMC!()) || 286 | (($AF) == GPIO_AF_OTG_HS_FS!()) || (($AF) == GPIO_AF_SDIO!()) || 287 | (($AF) == GPIO_AF_DCMI!()) || (($AF) == GPIO_AF_EVENTOUT!()));} 288 | 289 | /* GPIO_Legacy 290 | */ 291 | 292 | macro_rules! GPIO_Mode_AIN {() => (GPIO_Mode_AN!());} 293 | 294 | macro_rules! GPIO_AF_OTG1_FS {() => (GPIO_AF_OTG_FS!());} 295 | macro_rules! GPIO_AF_OTG2_HS {() => (GPIO_AF_OTG_HS!());} 296 | macro_rules! GPIO_AF_OTG2_FS {() => (GPIO_AF_OTG_HS_FS!());} 297 | 298 | // /* Exported macro ------------------------------------------------------------*/ 299 | // /* Exported functions --------------------------------------------------------*/ 300 | 301 | // /* Function used to set the GPIO configuration to the default reset state ****/ 302 | // void GPIO_DeInit(GPIO_TypeDef* GPIOx); 303 | 304 | // /* Initialization and Configuration functions *********************************/ 305 | // void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); 306 | // void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); 307 | // void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 308 | 309 | // /* GPIO Read and Write functions **********************************************/ 310 | // uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 311 | // uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); 312 | // uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 313 | // uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); 314 | // void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 315 | // void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 316 | // void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); 317 | // void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); 318 | // void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); 319 | 320 | // /* GPIO Alternate functions configuration function ****************************/ 321 | // void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); 322 | 323 | -------------------------------------------------------------------------------- /libarm/stm32f4xx_rcc.rs: -------------------------------------------------------------------------------- 1 | /* Bit definition for RCC_AHB1ENR register */ 2 | macro_rules! RCC_AHB1ENR_GPIOAEN {() => (0x00000001u32 as uint32_t);} 3 | macro_rules! RCC_AHB1ENR_GPIOBEN {() => (0x00000002u32 as uint32_t);} 4 | macro_rules! RCC_AHB1ENR_GPIOCEN {() => (0x00000004u32 as uint32_t);} 5 | macro_rules! RCC_AHB1ENR_GPIODEN {() => (0x00000008u32 as uint32_t);} 6 | macro_rules! RCC_AHB1ENR_GPIOEEN {() => (0x00000010u32 as uint32_t);} 7 | macro_rules! RCC_AHB1ENR_GPIOFEN {() => (0x00000020u32 as uint32_t);} 8 | macro_rules! RCC_AHB1ENR_GPIOGEN {() => (0x00000040u32 as uint32_t);} 9 | macro_rules! RCC_AHB1ENR_GPIOHEN {() => (0x00000080u32 as uint32_t);} 10 | macro_rules! RCC_AHB1ENR_GPIOIEN {() => (0x00000100u32 as uint32_t);} 11 | macro_rules! RCC_AHB1ENR_CRCEN {() => (0x00001000u32 as uint32_t);} 12 | macro_rules! RCC_AHB1ENR_BKPSRAMEN {() => (0x00040000u32 as uint32_t);} 13 | macro_rules! RCC_AHB1ENR_CCMDATARAMEN {() => (0x00100000u32 as uint32_t);} 14 | macro_rules! RCC_AHB1ENR_DMA1EN {() => (0x00200000u32 as uint32_t);} 15 | macro_rules! RCC_AHB1ENR_DMA2EN {() => (0x00400000u32 as uint32_t);} 16 | macro_rules! RCC_AHB1ENR_ETHMACEN {() => (0x02000000u32 as uint32_t);} 17 | macro_rules! RCC_AHB1ENR_ETHMACTXEN {() => (0x04000000u32 as uint32_t);} 18 | macro_rules! RCC_AHB1ENR_ETHMACRXEN {() => (0x08000000u32 as uint32_t);} 19 | macro_rules! RCC_AHB1ENR_ETHMACPTPEN {() => (0x10000000u32 as uint32_t);} 20 | macro_rules! RCC_AHB1ENR_OTGHSEN {() => (0x20000000u32 as uint32_t);} 21 | macro_rules! RCC_AHB1ENR_OTGHSULPIEN {() => (0x40000000u32 as uint32_t);} 22 | 23 | /* Bit definition for RCC_APB1ENR register */ 24 | macro_rules! RCC_APB1ENR_TIM2EN {() => (0x00000001u32 as uint32_t);} 25 | macro_rules! RCC_APB1ENR_TIM3EN {() => (0x00000002u32 as uint32_t);} 26 | macro_rules! RCC_APB1ENR_TIM4EN {() => (0x00000004u32 as uint32_t);} 27 | macro_rules! RCC_APB1ENR_TIM5EN {() => (0x00000008u32 as uint32_t);} 28 | macro_rules! RCC_APB1ENR_TIM6EN {() => (0x00000010u32 as uint32_t);} 29 | macro_rules! RCC_APB1ENR_TIM7EN {() => (0x00000020u32 as uint32_t);} 30 | macro_rules! RCC_APB1ENR_TIM12EN {() => (0x00000040u32 as uint32_t);} 31 | macro_rules! RCC_APB1ENR_TIM13EN {() => (0x00000080u32 as uint32_t);} 32 | macro_rules! RCC_APB1ENR_TIM14EN {() => (0x00000100u32 as uint32_t);} 33 | macro_rules! RCC_APB1ENR_WWDGEN {() => (0x00000800u32 as uint32_t);} 34 | macro_rules! RCC_APB1ENR_SPI2EN {() => (0x00004000u32 as uint32_t);} 35 | macro_rules! RCC_APB1ENR_SPI3EN {() => (0x00008000u32 as uint32_t);} 36 | macro_rules! RCC_APB1ENR_USART2EN {() => (0x00020000u32 as uint32_t);} 37 | macro_rules! RCC_APB1ENR_USART3EN {() => (0x00040000u32 as uint32_t);} 38 | macro_rules! RCC_APB1ENR_UART4EN {() => (0x00080000u32 as uint32_t);} 39 | macro_rules! RCC_APB1ENR_UART5EN {() => (0x00100000u32 as uint32_t);} 40 | macro_rules! RCC_APB1ENR_I2C1EN {() => (0x00200000u32 as uint32_t);} 41 | macro_rules! RCC_APB1ENR_I2C2EN {() => (0x00400000u32 as uint32_t);} 42 | macro_rules! RCC_APB1ENR_I2C3EN {() => (0x00800000u32 as uint32_t);} 43 | macro_rules! RCC_APB1ENR_CAN1EN {() => (0x02000000u32 as uint32_t);} 44 | macro_rules! RCC_APB1ENR_CAN2EN {() => (0x04000000u32 as uint32_t);} 45 | macro_rules! RCC_APB1ENR_PWREN {() => (0x10000000u32 as uint32_t);} 46 | macro_rules! RCC_APB1ENR_DACEN {() => (0x20000000u32 as uint32_t);} 47 | 48 | macro_rules! RCC_AHB1Periph_GPIOD {() => (0x00000008u32 as uint32_t);} 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /main.rs: -------------------------------------------------------------------------------- 1 | #![allow(improper_ctypes)] 2 | #![no_std] 3 | #![no_main] 4 | #![feature(lang_items)] 5 | #![feature(int_uint)] // update fail_bounds_check 6 | #![feature(no_std)] 7 | 8 | #![crate_name="blinky"] 9 | 10 | //extern crate libc; 11 | 12 | use zero::std_types::*; 13 | use libarm::stm32f4xx::*; 14 | 15 | mod zero { 16 | pub mod std_types; 17 | pub mod zero; 18 | } 19 | 20 | #[macro_use] 21 | mod libarm { 22 | #[macro_use] pub mod stm32f4xx; 23 | #[macro_use] pub mod stm32f4xx_gpio; 24 | #[macro_use] pub mod stm32f4xx_rcc; 25 | } 26 | 27 | const LED_GREEN :uint = 12; 28 | const LED_ORANGE :uint = 13; 29 | const LED_RED :uint = 14; 30 | const LED_BLUE :uint = 15; 31 | 32 | static LED :uint = LED_RED; 33 | 34 | #[no_mangle] 35 | pub extern "C" fn TIM2_IRQHandler() { 36 | let TIM2 = TIM2(); 37 | let GPIOD = GPIOD(); 38 | let toggle_led = 1 << LED; 39 | 40 | // flash on update event 41 | if TIM2.SR & TIM_SR_UIF!() > 0 { 42 | GPIOD.ODR ^= toggle_led; 43 | } 44 | 45 | TIM2.SR = 0x0; // reset the status register 46 | } 47 | 48 | 49 | #[no_mangle] 50 | pub extern "C" fn main() 51 | { 52 | let pin = LED; 53 | let RCC = RCC(); 54 | let GPIOD = GPIOD(); 55 | let TIM2 = TIM2(); 56 | let NVIC = NVIC(); 57 | 58 | let mode = GPIO_Mode_OUT!() << (pin * 2); 59 | let speed = GPIO_Speed_100MHz!() << (pin * 2); 60 | let otype = GPIO_OType_PP!() << pin; 61 | let pullup = GPIO_PuPd_NOPULL!() << (pin * 2); 62 | let irq_en = 1 << (TIM2_IRQn!() as uint); 63 | 64 | RCC.AHB1ENR |= RCC_AHB1ENR_GPIODEN!(); // enable the clock to GPIOD 65 | RCC.APB1ENR |= RCC_APB1ENR_TIM2EN!(); // enable TIM2 clock 66 | 67 | // 68 | // Initialise the GPIO port. 69 | // 70 | GPIOD.MODER |= mode; 71 | GPIOD.OSPEEDR |= speed; 72 | GPIOD.OTYPER |= otype; 73 | GPIOD.PUPDR |= pullup; 74 | 75 | NVIC.ISER[0] |= irq_en; // enable the TIM2 IRQ 76 | 77 | TIM2.PSC = 0xFFFF; // max prescaler 78 | TIM2.DIER |= TIM_DIER_UIE!(); // enable update interrupt 79 | TIM2.ARR = 0xFF; // count to 255 (autoreload value 255) 80 | TIM2.CR1 |= TIM_CR1_ARPE!() | TIM_CR1_CEN!(); // autoreload on, counter enabled 81 | TIM2.EGR = 1; // trigger update event to reload timer registers 82 | 83 | loop {} 84 | } 85 | 86 | -------------------------------------------------------------------------------- /sys/inc/core/arm_common_tables.h: -------------------------------------------------------------------------------- 1 | /* ---------------------------------------------------------------------- 2 | * Copyright (C) 2010 ARM Limited. All rights reserved. 3 | * 4 | * $Date: 11. November 2010 5 | * $Revision: V1.0.2 6 | * 7 | * Project: CMSIS DSP Library 8 | * Title: arm_common_tables.h 9 | * 10 | * Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions 11 | * 12 | * Target Processor: Cortex-M4/Cortex-M3 13 | * 14 | * Version 1.0.2 2010/11/11 15 | * Documentation updated. 16 | * 17 | * Version 1.0.1 2010/10/05 18 | * Production release and review comments incorporated. 19 | * 20 | * Version 1.0.0 2010/09/20 21 | * Production release and review comments incorporated. 22 | * -------------------------------------------------------------------- */ 23 | 24 | #ifndef _ARM_COMMON_TABLES_H 25 | #define _ARM_COMMON_TABLES_H 26 | 27 | #include "arm_math.h" 28 | 29 | extern uint16_t armBitRevTable[256]; 30 | extern q15_t armRecipTableQ15[64]; 31 | extern q31_t armRecipTableQ31[64]; 32 | extern const q31_t realCoefAQ31[1024]; 33 | extern const q31_t realCoefBQ31[1024]; 34 | 35 | #endif /* ARM_COMMON_TABLES_H */ 36 | -------------------------------------------------------------------------------- /sys/inc/core/core_cm0.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cm0.h 3 | * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File 4 | * @version V2.10 5 | * @date 19. July 2011 6 | * 7 | * @note 8 | * Copyright (C) 2009-2011 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | #if defined ( __ICCARM__ ) 24 | #pragma system_include /* treat file as system include file for MISRA check */ 25 | #endif 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #ifndef __CORE_CM0_H_GENERIC 32 | #define __CORE_CM0_H_GENERIC 33 | 34 | 35 | /** \mainpage CMSIS Cortex-M0 36 | 37 | This documentation describes the CMSIS Cortex-M Core Peripheral Access Layer. 38 | It consists of: 39 | 40 | - Cortex-M Core Register Definitions 41 | - Cortex-M functions 42 | - Cortex-M instructions 43 | 44 | The CMSIS Cortex-M0 Core Peripheral Access Layer contains C and assembly functions that ease 45 | access to the Cortex-M Core 46 | */ 47 | 48 | /** \defgroup CMSIS_MISRA_Exceptions CMSIS MISRA-C:2004 Compliance Exceptions 49 | CMSIS violates following MISRA-C2004 Rules: 50 | 51 | - Violates MISRA 2004 Required Rule 8.5, object/function definition in header file.
52 | Function definitions in header files are used to allow 'inlining'. 53 | 54 | - Violates MISRA 2004 Required Rule 18.4, declaration of union type or object of union type: '{...}'.
55 | Unions are used for effective representation of core registers. 56 | 57 | - Violates MISRA 2004 Advisory Rule 19.7, Function-like macro defined.
58 | Function-like macros are used to allow more efficient code. 59 | 60 | */ 61 | 62 | 63 | /******************************************************************************* 64 | * CMSIS definitions 65 | ******************************************************************************/ 66 | /** \defgroup CMSIS_core_definitions CMSIS Core Definitions 67 | This file defines all structures and symbols for CMSIS core: 68 | - CMSIS version number 69 | - Cortex-M core 70 | - Cortex-M core Revision Number 71 | @{ 72 | */ 73 | 74 | /* CMSIS CM0 definitions */ 75 | #define __CM0_CMSIS_VERSION_MAIN (0x02) /*!< [31:16] CMSIS HAL main version */ 76 | #define __CM0_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */ 77 | #define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16) | __CM0_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ 78 | 79 | #define __CORTEX_M (0x00) /*!< Cortex core */ 80 | 81 | 82 | #if defined ( __CC_ARM ) 83 | #define __ASM __asm /*!< asm keyword for ARM Compiler */ 84 | #define __INLINE __inline /*!< inline keyword for ARM Compiler */ 85 | 86 | #elif defined ( __ICCARM__ ) 87 | #define __ASM __asm /*!< asm keyword for IAR Compiler */ 88 | #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ 89 | 90 | #elif defined ( __GNUC__ ) 91 | #define __ASM __asm /*!< asm keyword for GNU Compiler */ 92 | #define __INLINE inline /*!< inline keyword for GNU Compiler */ 93 | 94 | #elif defined ( __TASKING__ ) 95 | #define __ASM __asm /*!< asm keyword for TASKING Compiler */ 96 | #define __INLINE inline /*!< inline keyword for TASKING Compiler */ 97 | 98 | #endif 99 | 100 | /*!< __FPU_USED to be checked prior to making use of FPU specific registers and functions */ 101 | #define __FPU_USED 0 102 | 103 | #if defined ( __CC_ARM ) 104 | #if defined __TARGET_FPU_VFP 105 | #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 106 | #endif 107 | #elif defined ( __ICCARM__ ) 108 | #if defined __ARMVFP__ 109 | #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 110 | #endif 111 | 112 | #elif defined ( __GNUC__ ) 113 | #if defined (__VFP_FP__) && !defined(__SOFTFP__) 114 | #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" 115 | #endif 116 | 117 | #elif defined ( __TASKING__ ) 118 | /* add preprocessor checks */ 119 | #endif 120 | 121 | #include /*!< standard types definitions */ 122 | #include "core_cmInstr.h" /*!< Core Instruction Access */ 123 | #include "core_cmFunc.h" /*!< Core Function Access */ 124 | 125 | #endif /* __CORE_CM0_H_GENERIC */ 126 | 127 | #ifndef __CMSIS_GENERIC 128 | 129 | #ifndef __CORE_CM0_H_DEPENDANT 130 | #define __CORE_CM0_H_DEPENDANT 131 | 132 | /* check device defines and use defaults */ 133 | #if defined __CHECK_DEVICE_DEFINES 134 | #ifndef __CM0_REV 135 | #define __CM0_REV 0x0000 136 | #warning "__CM0_REV not defined in device header file; using default!" 137 | #endif 138 | 139 | #ifndef __NVIC_PRIO_BITS 140 | #define __NVIC_PRIO_BITS 2 141 | #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" 142 | #endif 143 | 144 | #ifndef __Vendor_SysTickConfig 145 | #define __Vendor_SysTickConfig 0 146 | #warning "__Vendor_SysTickConfig not defined in device header file; using default!" 147 | #endif 148 | #endif 149 | 150 | /* IO definitions (access restrictions to peripheral registers) */ 151 | #ifdef __cplusplus 152 | #define __I volatile /*!< defines 'read only' permissions */ 153 | #else 154 | #define __I volatile const /*!< defines 'read only' permissions */ 155 | #endif 156 | #define __O volatile /*!< defines 'write only' permissions */ 157 | #define __IO volatile /*!< defines 'read / write' permissions */ 158 | 159 | /*@} end of group CMSIS_core_definitions */ 160 | 161 | 162 | 163 | /******************************************************************************* 164 | * Register Abstraction 165 | ******************************************************************************/ 166 | /** \defgroup CMSIS_core_register CMSIS Core Register 167 | Core Register contain: 168 | - Core Register 169 | - Core NVIC Register 170 | - Core SCB Register 171 | - Core SysTick Register 172 | */ 173 | 174 | /** \ingroup CMSIS_core_register 175 | \defgroup CMSIS_CORE CMSIS Core 176 | Type definitions for the Cortex-M Core Registers 177 | @{ 178 | */ 179 | 180 | /** \brief Union type to access the Application Program Status Register (APSR). 181 | */ 182 | typedef union 183 | { 184 | struct 185 | { 186 | #if (__CORTEX_M != 0x04) 187 | uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ 188 | #else 189 | uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ 190 | uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ 191 | uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ 192 | #endif 193 | uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ 194 | uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ 195 | uint32_t C:1; /*!< bit: 29 Carry condition code flag */ 196 | uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ 197 | uint32_t N:1; /*!< bit: 31 Negative condition code flag */ 198 | } b; /*!< Structure used for bit access */ 199 | uint32_t w; /*!< Type used for word access */ 200 | } APSR_Type; 201 | 202 | 203 | /** \brief Union type to access the Interrupt Program Status Register (IPSR). 204 | */ 205 | typedef union 206 | { 207 | struct 208 | { 209 | uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ 210 | uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ 211 | } b; /*!< Structure used for bit access */ 212 | uint32_t w; /*!< Type used for word access */ 213 | } IPSR_Type; 214 | 215 | 216 | /** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). 217 | */ 218 | typedef union 219 | { 220 | struct 221 | { 222 | uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ 223 | #if (__CORTEX_M != 0x04) 224 | uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ 225 | #else 226 | uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ 227 | uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ 228 | uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ 229 | #endif 230 | uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ 231 | uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ 232 | uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ 233 | uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ 234 | uint32_t C:1; /*!< bit: 29 Carry condition code flag */ 235 | uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ 236 | uint32_t N:1; /*!< bit: 31 Negative condition code flag */ 237 | } b; /*!< Structure used for bit access */ 238 | uint32_t w; /*!< Type used for word access */ 239 | } xPSR_Type; 240 | 241 | 242 | /** \brief Union type to access the Control Registers (CONTROL). 243 | */ 244 | typedef union 245 | { 246 | struct 247 | { 248 | uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ 249 | uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ 250 | uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ 251 | uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ 252 | } b; /*!< Structure used for bit access */ 253 | uint32_t w; /*!< Type used for word access */ 254 | } CONTROL_Type; 255 | 256 | /*@} end of group CMSIS_CORE */ 257 | 258 | 259 | /** \ingroup CMSIS_core_register 260 | \defgroup CMSIS_NVIC CMSIS NVIC 261 | Type definitions for the Cortex-M NVIC Registers 262 | @{ 263 | */ 264 | 265 | /** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). 266 | */ 267 | typedef struct 268 | { 269 | __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ 270 | uint32_t RESERVED0[31]; 271 | __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ 272 | uint32_t RSERVED1[31]; 273 | __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ 274 | uint32_t RESERVED2[31]; 275 | __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ 276 | uint32_t RESERVED3[31]; 277 | uint32_t RESERVED4[64]; 278 | __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ 279 | } NVIC_Type; 280 | 281 | /*@} end of group CMSIS_NVIC */ 282 | 283 | 284 | /** \ingroup CMSIS_core_register 285 | \defgroup CMSIS_SCB CMSIS SCB 286 | Type definitions for the Cortex-M System Control Block Registers 287 | @{ 288 | */ 289 | 290 | /** \brief Structure type to access the System Control Block (SCB). 291 | */ 292 | typedef struct 293 | { 294 | __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ 295 | __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ 296 | uint32_t RESERVED0; 297 | __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ 298 | __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ 299 | __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ 300 | uint32_t RESERVED1; 301 | __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ 302 | __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ 303 | } SCB_Type; 304 | 305 | /* SCB CPUID Register Definitions */ 306 | #define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ 307 | #define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ 308 | 309 | #define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ 310 | #define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ 311 | 312 | #define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ 313 | #define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ 314 | 315 | #define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ 316 | #define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ 317 | 318 | #define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ 319 | #define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ 320 | 321 | /* SCB Interrupt Control State Register Definitions */ 322 | #define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ 323 | #define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ 324 | 325 | #define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ 326 | #define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ 327 | 328 | #define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ 329 | #define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ 330 | 331 | #define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ 332 | #define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ 333 | 334 | #define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ 335 | #define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ 336 | 337 | #define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ 338 | #define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ 339 | 340 | #define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ 341 | #define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ 342 | 343 | #define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ 344 | #define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ 345 | 346 | #define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ 347 | #define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ 348 | 349 | /* SCB Application Interrupt and Reset Control Register Definitions */ 350 | #define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ 351 | #define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ 352 | 353 | #define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ 354 | #define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ 355 | 356 | #define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ 357 | #define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ 358 | 359 | #define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ 360 | #define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ 361 | 362 | #define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ 363 | #define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ 364 | 365 | /* SCB System Control Register Definitions */ 366 | #define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ 367 | #define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ 368 | 369 | #define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ 370 | #define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ 371 | 372 | #define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ 373 | #define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ 374 | 375 | /* SCB Configuration Control Register Definitions */ 376 | #define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ 377 | #define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ 378 | 379 | #define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ 380 | #define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ 381 | 382 | /* SCB System Handler Control and State Register Definitions */ 383 | #define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ 384 | #define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ 385 | 386 | /*@} end of group CMSIS_SCB */ 387 | 388 | 389 | /** \ingroup CMSIS_core_register 390 | \defgroup CMSIS_SysTick CMSIS SysTick 391 | Type definitions for the Cortex-M System Timer Registers 392 | @{ 393 | */ 394 | 395 | /** \brief Structure type to access the System Timer (SysTick). 396 | */ 397 | typedef struct 398 | { 399 | __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ 400 | __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ 401 | __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ 402 | __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ 403 | } SysTick_Type; 404 | 405 | /* SysTick Control / Status Register Definitions */ 406 | #define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ 407 | #define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ 408 | 409 | #define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ 410 | #define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ 411 | 412 | #define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ 413 | #define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ 414 | 415 | #define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ 416 | #define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ 417 | 418 | /* SysTick Reload Register Definitions */ 419 | #define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ 420 | #define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ 421 | 422 | /* SysTick Current Register Definitions */ 423 | #define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ 424 | #define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ 425 | 426 | /* SysTick Calibration Register Definitions */ 427 | #define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ 428 | #define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ 429 | 430 | #define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ 431 | #define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ 432 | 433 | #define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ 434 | #define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ 435 | 436 | /*@} end of group CMSIS_SysTick */ 437 | 438 | 439 | /** \ingroup CMSIS_core_register 440 | \defgroup CMSIS_CoreDebug CMSIS Core Debug 441 | Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP 442 | and not via processor. Therefore they are not covered by the Cortex-M0 header file. 443 | @{ 444 | */ 445 | /*@} end of group CMSIS_CoreDebug */ 446 | 447 | 448 | /** \ingroup CMSIS_core_register 449 | @{ 450 | */ 451 | 452 | /* Memory mapping of Cortex-M0 Hardware */ 453 | #define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ 454 | #define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ 455 | #define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ 456 | #define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ 457 | #define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ 458 | 459 | #define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ 460 | #define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ 461 | #define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ 462 | 463 | 464 | /*@} */ 465 | 466 | 467 | 468 | /******************************************************************************* 469 | * Hardware Abstraction Layer 470 | ******************************************************************************/ 471 | /** \defgroup CMSIS_Core_FunctionInterface CMSIS Core Function Interface 472 | Core Function Interface contains: 473 | - Core NVIC Functions 474 | - Core SysTick Functions 475 | - Core Register Access Functions 476 | */ 477 | 478 | 479 | 480 | /* ########################## NVIC functions #################################### */ 481 | /** \ingroup CMSIS_Core_FunctionInterface 482 | \defgroup CMSIS_Core_NVICFunctions CMSIS Core NVIC Functions 483 | @{ 484 | */ 485 | 486 | /* Interrupt Priorities are WORD accessible only under ARMv6M */ 487 | /* The following MACROS handle generation of the register offset and byte masks */ 488 | #define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) 489 | #define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) 490 | #define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) 491 | 492 | 493 | /** \brief Enable External Interrupt 494 | 495 | This function enables a device specific interrupt in the NVIC interrupt controller. 496 | The interrupt number cannot be a negative value. 497 | 498 | \param [in] IRQn Number of the external interrupt to enable 499 | */ 500 | static __INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) 501 | { 502 | NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); 503 | } 504 | 505 | 506 | /** \brief Disable External Interrupt 507 | 508 | This function disables a device specific interrupt in the NVIC interrupt controller. 509 | The interrupt number cannot be a negative value. 510 | 511 | \param [in] IRQn Number of the external interrupt to disable 512 | */ 513 | static __INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) 514 | { 515 | NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); 516 | } 517 | 518 | 519 | /** \brief Get Pending Interrupt 520 | 521 | This function reads the pending register in the NVIC and returns the pending bit 522 | for the specified interrupt. 523 | 524 | \param [in] IRQn Number of the interrupt for get pending 525 | \return 0 Interrupt status is not pending 526 | \return 1 Interrupt status is pending 527 | */ 528 | static __INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) 529 | { 530 | return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); 531 | } 532 | 533 | 534 | /** \brief Set Pending Interrupt 535 | 536 | This function sets the pending bit for the specified interrupt. 537 | The interrupt number cannot be a negative value. 538 | 539 | \param [in] IRQn Number of the interrupt for set pending 540 | */ 541 | static __INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) 542 | { 543 | NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); 544 | } 545 | 546 | 547 | /** \brief Clear Pending Interrupt 548 | 549 | This function clears the pending bit for the specified interrupt. 550 | The interrupt number cannot be a negative value. 551 | 552 | \param [in] IRQn Number of the interrupt for clear pending 553 | */ 554 | static __INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) 555 | { 556 | NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ 557 | } 558 | 559 | 560 | /** \brief Set Interrupt Priority 561 | 562 | This function sets the priority for the specified interrupt. The interrupt 563 | number can be positive to specify an external (device specific) 564 | interrupt, or negative to specify an internal (core) interrupt. 565 | 566 | Note: The priority cannot be set for every core interrupt. 567 | 568 | \param [in] IRQn Number of the interrupt for set priority 569 | \param [in] priority Priority to set 570 | */ 571 | static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) 572 | { 573 | if(IRQn < 0) { 574 | SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | 575 | (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } 576 | else { 577 | NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | 578 | (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } 579 | } 580 | 581 | 582 | /** \brief Get Interrupt Priority 583 | 584 | This function reads the priority for the specified interrupt. The interrupt 585 | number can be positive to specify an external (device specific) 586 | interrupt, or negative to specify an internal (core) interrupt. 587 | 588 | The returned priority value is automatically aligned to the implemented 589 | priority bits of the microcontroller. 590 | 591 | \param [in] IRQn Number of the interrupt for get priority 592 | \return Interrupt Priority 593 | */ 594 | static __INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) 595 | { 596 | 597 | if(IRQn < 0) { 598 | return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0 system interrupts */ 599 | else { 600 | return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ 601 | } 602 | 603 | 604 | /** \brief System Reset 605 | 606 | This function initiate a system reset request to reset the MCU. 607 | */ 608 | static __INLINE void NVIC_SystemReset(void) 609 | { 610 | __DSB(); /* Ensure all outstanding memory accesses included 611 | buffered write are completed before reset */ 612 | SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | 613 | SCB_AIRCR_SYSRESETREQ_Msk); 614 | __DSB(); /* Ensure completion of memory access */ 615 | while(1); /* wait until reset */ 616 | } 617 | 618 | /*@} end of CMSIS_Core_NVICFunctions */ 619 | 620 | 621 | 622 | /* ################################## SysTick function ############################################ */ 623 | /** \ingroup CMSIS_Core_FunctionInterface 624 | \defgroup CMSIS_Core_SysTickFunctions CMSIS Core SysTick Functions 625 | @{ 626 | */ 627 | 628 | #if (__Vendor_SysTickConfig == 0) 629 | 630 | /** \brief System Tick Configuration 631 | 632 | This function initialises the system tick timer and its interrupt and start the system tick timer. 633 | Counter is in free running mode to generate periodical interrupts. 634 | 635 | \param [in] ticks Number of ticks between two interrupts 636 | \return 0 Function succeeded 637 | \return 1 Function failed 638 | */ 639 | static __INLINE uint32_t SysTick_Config(uint32_t ticks) 640 | { 641 | if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ 642 | 643 | SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ 644 | NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */ 645 | SysTick->VAL = 0; /* Load the SysTick Counter Value */ 646 | SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 647 | SysTick_CTRL_TICKINT_Msk | 648 | SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ 649 | return (0); /* Function successful */ 650 | } 651 | 652 | #endif 653 | 654 | /*@} end of CMSIS_Core_SysTickFunctions */ 655 | 656 | 657 | 658 | 659 | #endif /* __CORE_CM0_H_DEPENDANT */ 660 | 661 | #endif /* __CMSIS_GENERIC */ 662 | 663 | #ifdef __cplusplus 664 | } 665 | #endif 666 | -------------------------------------------------------------------------------- /sys/inc/core/core_cm4_simd.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cm4_simd.h 3 | * @brief CMSIS Cortex-M4 SIMD Header File 4 | * @version V2.10 5 | * @date 19. July 2011 6 | * 7 | * @note 8 | * Copyright (C) 2010-2011 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #ifndef __CORE_CM4_SIMD_H 29 | #define __CORE_CM4_SIMD_H 30 | 31 | 32 | /******************************************************************************* 33 | * Hardware Abstraction Layer 34 | ******************************************************************************/ 35 | 36 | 37 | /* ################### Compiler specific Intrinsics ########################### */ 38 | /** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics 39 | Access to dedicated SIMD instructions 40 | @{ 41 | */ 42 | 43 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 44 | /* ARM armcc specific functions */ 45 | 46 | /*------ CM4 SOMD Intrinsics -----------------------------------------------------*/ 47 | #define __SADD8 __sadd8 48 | #define __QADD8 __qadd8 49 | #define __SHADD8 __shadd8 50 | #define __UADD8 __uadd8 51 | #define __UQADD8 __uqadd8 52 | #define __UHADD8 __uhadd8 53 | #define __SSUB8 __ssub8 54 | #define __QSUB8 __qsub8 55 | #define __SHSUB8 __shsub8 56 | #define __USUB8 __usub8 57 | #define __UQSUB8 __uqsub8 58 | #define __UHSUB8 __uhsub8 59 | #define __SADD16 __sadd16 60 | #define __QADD16 __qadd16 61 | #define __SHADD16 __shadd16 62 | #define __UADD16 __uadd16 63 | #define __UQADD16 __uqadd16 64 | #define __UHADD16 __uhadd16 65 | #define __SSUB16 __ssub16 66 | #define __QSUB16 __qsub16 67 | #define __SHSUB16 __shsub16 68 | #define __USUB16 __usub16 69 | #define __UQSUB16 __uqsub16 70 | #define __UHSUB16 __uhsub16 71 | #define __SASX __sasx 72 | #define __QASX __qasx 73 | #define __SHASX __shasx 74 | #define __UASX __uasx 75 | #define __UQASX __uqasx 76 | #define __UHASX __uhasx 77 | #define __SSAX __ssax 78 | #define __QSAX __qsax 79 | #define __SHSAX __shsax 80 | #define __USAX __usax 81 | #define __UQSAX __uqsax 82 | #define __UHSAX __uhsax 83 | #define __USAD8 __usad8 84 | #define __USADA8 __usada8 85 | #define __SSAT16 __ssat16 86 | #define __USAT16 __usat16 87 | #define __UXTB16 __uxtb16 88 | #define __UXTAB16 __uxtab16 89 | #define __SXTB16 __sxtb16 90 | #define __SXTAB16 __sxtab16 91 | #define __SMUAD __smuad 92 | #define __SMUADX __smuadx 93 | #define __SMLAD __smlad 94 | #define __SMLADX __smladx 95 | #define __SMLALD __smlald 96 | #define __SMLALDX __smlaldx 97 | #define __SMUSD __smusd 98 | #define __SMUSDX __smusdx 99 | #define __SMLSD __smlsd 100 | #define __SMLSDX __smlsdx 101 | #define __SMLSLD __smlsld 102 | #define __SMLSLDX __smlsldx 103 | #define __SEL __sel 104 | #define __QADD __qadd 105 | #define __QSUB __qsub 106 | 107 | #define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ 108 | ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) 109 | 110 | #define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ 111 | ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) 112 | 113 | 114 | /*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ 115 | 116 | 117 | 118 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 119 | /* IAR iccarm specific functions */ 120 | 121 | #include 122 | 123 | /*------ CM4 SIMDDSP Intrinsics -----------------------------------------------------*/ 124 | /* intrinsic __SADD8 see intrinsics.h */ 125 | /* intrinsic __QADD8 see intrinsics.h */ 126 | /* intrinsic __SHADD8 see intrinsics.h */ 127 | /* intrinsic __UADD8 see intrinsics.h */ 128 | /* intrinsic __UQADD8 see intrinsics.h */ 129 | /* intrinsic __UHADD8 see intrinsics.h */ 130 | /* intrinsic __SSUB8 see intrinsics.h */ 131 | /* intrinsic __QSUB8 see intrinsics.h */ 132 | /* intrinsic __SHSUB8 see intrinsics.h */ 133 | /* intrinsic __USUB8 see intrinsics.h */ 134 | /* intrinsic __UQSUB8 see intrinsics.h */ 135 | /* intrinsic __UHSUB8 see intrinsics.h */ 136 | /* intrinsic __SADD16 see intrinsics.h */ 137 | /* intrinsic __QADD16 see intrinsics.h */ 138 | /* intrinsic __SHADD16 see intrinsics.h */ 139 | /* intrinsic __UADD16 see intrinsics.h */ 140 | /* intrinsic __UQADD16 see intrinsics.h */ 141 | /* intrinsic __UHADD16 see intrinsics.h */ 142 | /* intrinsic __SSUB16 see intrinsics.h */ 143 | /* intrinsic __QSUB16 see intrinsics.h */ 144 | /* intrinsic __SHSUB16 see intrinsics.h */ 145 | /* intrinsic __USUB16 see intrinsics.h */ 146 | /* intrinsic __UQSUB16 see intrinsics.h */ 147 | /* intrinsic __UHSUB16 see intrinsics.h */ 148 | /* intrinsic __SASX see intrinsics.h */ 149 | /* intrinsic __QASX see intrinsics.h */ 150 | /* intrinsic __SHASX see intrinsics.h */ 151 | /* intrinsic __UASX see intrinsics.h */ 152 | /* intrinsic __UQASX see intrinsics.h */ 153 | /* intrinsic __UHASX see intrinsics.h */ 154 | /* intrinsic __SSAX see intrinsics.h */ 155 | /* intrinsic __QSAX see intrinsics.h */ 156 | /* intrinsic __SHSAX see intrinsics.h */ 157 | /* intrinsic __USAX see intrinsics.h */ 158 | /* intrinsic __UQSAX see intrinsics.h */ 159 | /* intrinsic __UHSAX see intrinsics.h */ 160 | /* intrinsic __USAD8 see intrinsics.h */ 161 | /* intrinsic __USADA8 see intrinsics.h */ 162 | /* intrinsic __SSAT16 see intrinsics.h */ 163 | /* intrinsic __USAT16 see intrinsics.h */ 164 | /* intrinsic __UXTB16 see intrinsics.h */ 165 | /* intrinsic __SXTB16 see intrinsics.h */ 166 | /* intrinsic __UXTAB16 see intrinsics.h */ 167 | /* intrinsic __SXTAB16 see intrinsics.h */ 168 | /* intrinsic __SMUAD see intrinsics.h */ 169 | /* intrinsic __SMUADX see intrinsics.h */ 170 | /* intrinsic __SMLAD see intrinsics.h */ 171 | /* intrinsic __SMLADX see intrinsics.h */ 172 | /* intrinsic __SMLALD see intrinsics.h */ 173 | /* intrinsic __SMLALDX see intrinsics.h */ 174 | /* intrinsic __SMUSD see intrinsics.h */ 175 | /* intrinsic __SMUSDX see intrinsics.h */ 176 | /* intrinsic __SMLSD see intrinsics.h */ 177 | /* intrinsic __SMLSDX see intrinsics.h */ 178 | /* intrinsic __SMLSLD see intrinsics.h */ 179 | /* intrinsic __SMLSLDX see intrinsics.h */ 180 | /* intrinsic __SEL see intrinsics.h */ 181 | /* intrinsic __QADD see intrinsics.h */ 182 | /* intrinsic __QSUB see intrinsics.h */ 183 | /* intrinsic __PKHBT see intrinsics.h */ 184 | /* intrinsic __PKHTB see intrinsics.h */ 185 | 186 | /*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ 187 | 188 | 189 | 190 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 191 | /* GNU gcc specific functions */ 192 | 193 | /*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ 194 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) 195 | { 196 | uint32_t result; 197 | 198 | __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 199 | return(result); 200 | } 201 | 202 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) 203 | { 204 | uint32_t result; 205 | 206 | __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 207 | return(result); 208 | } 209 | 210 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) 211 | { 212 | uint32_t result; 213 | 214 | __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 215 | return(result); 216 | } 217 | 218 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) 219 | { 220 | uint32_t result; 221 | 222 | __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 223 | return(result); 224 | } 225 | 226 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) 227 | { 228 | uint32_t result; 229 | 230 | __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 231 | return(result); 232 | } 233 | 234 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) 235 | { 236 | uint32_t result; 237 | 238 | __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 239 | return(result); 240 | } 241 | 242 | 243 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) 244 | { 245 | uint32_t result; 246 | 247 | __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 248 | return(result); 249 | } 250 | 251 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) 252 | { 253 | uint32_t result; 254 | 255 | __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 256 | return(result); 257 | } 258 | 259 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) 260 | { 261 | uint32_t result; 262 | 263 | __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 264 | return(result); 265 | } 266 | 267 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) 268 | { 269 | uint32_t result; 270 | 271 | __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 272 | return(result); 273 | } 274 | 275 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) 276 | { 277 | uint32_t result; 278 | 279 | __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 280 | return(result); 281 | } 282 | 283 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) 284 | { 285 | uint32_t result; 286 | 287 | __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 288 | return(result); 289 | } 290 | 291 | 292 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) 293 | { 294 | uint32_t result; 295 | 296 | __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 297 | return(result); 298 | } 299 | 300 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) 301 | { 302 | uint32_t result; 303 | 304 | __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 305 | return(result); 306 | } 307 | 308 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) 309 | { 310 | uint32_t result; 311 | 312 | __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 313 | return(result); 314 | } 315 | 316 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) 317 | { 318 | uint32_t result; 319 | 320 | __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 321 | return(result); 322 | } 323 | 324 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) 325 | { 326 | uint32_t result; 327 | 328 | __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 329 | return(result); 330 | } 331 | 332 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) 333 | { 334 | uint32_t result; 335 | 336 | __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 337 | return(result); 338 | } 339 | 340 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) 341 | { 342 | uint32_t result; 343 | 344 | __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 345 | return(result); 346 | } 347 | 348 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) 349 | { 350 | uint32_t result; 351 | 352 | __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 353 | return(result); 354 | } 355 | 356 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) 357 | { 358 | uint32_t result; 359 | 360 | __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 361 | return(result); 362 | } 363 | 364 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) 365 | { 366 | uint32_t result; 367 | 368 | __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 369 | return(result); 370 | } 371 | 372 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) 373 | { 374 | uint32_t result; 375 | 376 | __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 377 | return(result); 378 | } 379 | 380 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) 381 | { 382 | uint32_t result; 383 | 384 | __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 385 | return(result); 386 | } 387 | 388 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) 389 | { 390 | uint32_t result; 391 | 392 | __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 393 | return(result); 394 | } 395 | 396 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) 397 | { 398 | uint32_t result; 399 | 400 | __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 401 | return(result); 402 | } 403 | 404 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) 405 | { 406 | uint32_t result; 407 | 408 | __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 409 | return(result); 410 | } 411 | 412 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) 413 | { 414 | uint32_t result; 415 | 416 | __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 417 | return(result); 418 | } 419 | 420 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) 421 | { 422 | uint32_t result; 423 | 424 | __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 425 | return(result); 426 | } 427 | 428 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) 429 | { 430 | uint32_t result; 431 | 432 | __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 433 | return(result); 434 | } 435 | 436 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) 437 | { 438 | uint32_t result; 439 | 440 | __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 441 | return(result); 442 | } 443 | 444 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) 445 | { 446 | uint32_t result; 447 | 448 | __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 449 | return(result); 450 | } 451 | 452 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) 453 | { 454 | uint32_t result; 455 | 456 | __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 457 | return(result); 458 | } 459 | 460 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) 461 | { 462 | uint32_t result; 463 | 464 | __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 465 | return(result); 466 | } 467 | 468 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) 469 | { 470 | uint32_t result; 471 | 472 | __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 473 | return(result); 474 | } 475 | 476 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) 477 | { 478 | uint32_t result; 479 | 480 | __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 481 | return(result); 482 | } 483 | 484 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) 485 | { 486 | uint32_t result; 487 | 488 | __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 489 | return(result); 490 | } 491 | 492 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) 493 | { 494 | uint32_t result; 495 | 496 | __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); 497 | return(result); 498 | } 499 | 500 | #define __SSAT16(ARG1,ARG2) \ 501 | ({ \ 502 | uint32_t __RES, __ARG1 = (ARG1); \ 503 | __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 504 | __RES; \ 505 | }) 506 | 507 | #define __USAT16(ARG1,ARG2) \ 508 | ({ \ 509 | uint32_t __RES, __ARG1 = (ARG1); \ 510 | __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 511 | __RES; \ 512 | }) 513 | 514 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTB16(uint32_t op1) 515 | { 516 | uint32_t result; 517 | 518 | __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); 519 | return(result); 520 | } 521 | 522 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) 523 | { 524 | uint32_t result; 525 | 526 | __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 527 | return(result); 528 | } 529 | 530 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTB16(uint32_t op1) 531 | { 532 | uint32_t result; 533 | 534 | __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); 535 | return(result); 536 | } 537 | 538 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) 539 | { 540 | uint32_t result; 541 | 542 | __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 543 | return(result); 544 | } 545 | 546 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) 547 | { 548 | uint32_t result; 549 | 550 | __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 551 | return(result); 552 | } 553 | 554 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) 555 | { 556 | uint32_t result; 557 | 558 | __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 559 | return(result); 560 | } 561 | 562 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) 563 | { 564 | uint32_t result; 565 | 566 | __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); 567 | return(result); 568 | } 569 | 570 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) 571 | { 572 | uint32_t result; 573 | 574 | __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); 575 | return(result); 576 | } 577 | 578 | #define __SMLALD(ARG1,ARG2,ARG3) \ 579 | ({ \ 580 | uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ 581 | __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ 582 | (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ 583 | }) 584 | 585 | #define __SMLALDX(ARG1,ARG2,ARG3) \ 586 | ({ \ 587 | uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ 588 | __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ 589 | (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ 590 | }) 591 | 592 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) 593 | { 594 | uint32_t result; 595 | 596 | __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 597 | return(result); 598 | } 599 | 600 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) 601 | { 602 | uint32_t result; 603 | 604 | __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 605 | return(result); 606 | } 607 | 608 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) 609 | { 610 | uint32_t result; 611 | 612 | __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); 613 | return(result); 614 | } 615 | 616 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) 617 | { 618 | uint32_t result; 619 | 620 | __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); 621 | return(result); 622 | } 623 | 624 | #define __SMLSLD(ARG1,ARG2,ARG3) \ 625 | ({ \ 626 | uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ 627 | __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ 628 | (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ 629 | }) 630 | 631 | #define __SMLSLDX(ARG1,ARG2,ARG3) \ 632 | ({ \ 633 | uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ 634 | __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ 635 | (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ 636 | }) 637 | 638 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) 639 | { 640 | uint32_t result; 641 | 642 | __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 643 | return(result); 644 | } 645 | 646 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) 647 | { 648 | uint32_t result; 649 | 650 | __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 651 | return(result); 652 | } 653 | 654 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) 655 | { 656 | uint32_t result; 657 | 658 | __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); 659 | return(result); 660 | } 661 | 662 | #define __PKHBT(ARG1,ARG2,ARG3) \ 663 | ({ \ 664 | uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ 665 | __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ 666 | __RES; \ 667 | }) 668 | 669 | #define __PKHTB(ARG1,ARG2,ARG3) \ 670 | ({ \ 671 | uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ 672 | if (ARG3 == 0) \ 673 | __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ 674 | else \ 675 | __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ 676 | __RES; \ 677 | }) 678 | 679 | /*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ 680 | 681 | 682 | 683 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 684 | /* TASKING carm specific functions */ 685 | 686 | 687 | /*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ 688 | /* not yet supported */ 689 | /*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ 690 | 691 | 692 | #endif 693 | 694 | /*@} end of group CMSIS_SIMD_intrinsics */ 695 | 696 | 697 | #endif /* __CORE_CM4_SIMD_H */ 698 | 699 | #ifdef __cplusplus 700 | } 701 | #endif 702 | -------------------------------------------------------------------------------- /sys/inc/core/core_cmFunc.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cmFunc.h 3 | * @brief CMSIS Cortex-M Core Function Access Header File 4 | * @version V2.10 5 | * @date 26. July 2011 6 | * 7 | * @note 8 | * Copyright (C) 2009-2011 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef __CORE_CMFUNC_H 25 | #define __CORE_CMFUNC_H 26 | 27 | 28 | /* ########################### Core Function Access ########################### */ 29 | /** \ingroup CMSIS_Core_FunctionInterface 30 | \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions 31 | @{ 32 | */ 33 | 34 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 35 | /* ARM armcc specific functions */ 36 | 37 | #if (__ARMCC_VERSION < 400677) 38 | #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 39 | #endif 40 | 41 | /* intrinsic void __enable_irq(); */ 42 | /* intrinsic void __disable_irq(); */ 43 | 44 | /** \brief Get Control Register 45 | 46 | This function returns the content of the Control Register. 47 | 48 | \return Control Register value 49 | */ 50 | static __INLINE uint32_t __get_CONTROL(void) 51 | { 52 | register uint32_t __regControl __ASM("control"); 53 | return(__regControl); 54 | } 55 | 56 | 57 | /** \brief Set Control Register 58 | 59 | This function writes the given value to the Control Register. 60 | 61 | \param [in] control Control Register value to set 62 | */ 63 | static __INLINE void __set_CONTROL(uint32_t control) 64 | { 65 | register uint32_t __regControl __ASM("control"); 66 | __regControl = control; 67 | } 68 | 69 | 70 | /** \brief Get ISPR Register 71 | 72 | This function returns the content of the ISPR Register. 73 | 74 | \return ISPR Register value 75 | */ 76 | static __INLINE uint32_t __get_IPSR(void) 77 | { 78 | register uint32_t __regIPSR __ASM("ipsr"); 79 | return(__regIPSR); 80 | } 81 | 82 | 83 | /** \brief Get APSR Register 84 | 85 | This function returns the content of the APSR Register. 86 | 87 | \return APSR Register value 88 | */ 89 | static __INLINE uint32_t __get_APSR(void) 90 | { 91 | register uint32_t __regAPSR __ASM("apsr"); 92 | return(__regAPSR); 93 | } 94 | 95 | 96 | /** \brief Get xPSR Register 97 | 98 | This function returns the content of the xPSR Register. 99 | 100 | \return xPSR Register value 101 | */ 102 | static __INLINE uint32_t __get_xPSR(void) 103 | { 104 | register uint32_t __regXPSR __ASM("xpsr"); 105 | return(__regXPSR); 106 | } 107 | 108 | 109 | /** \brief Get Process Stack Pointer 110 | 111 | This function returns the current value of the Process Stack Pointer (PSP). 112 | 113 | \return PSP Register value 114 | */ 115 | static __INLINE uint32_t __get_PSP(void) 116 | { 117 | register uint32_t __regProcessStackPointer __ASM("psp"); 118 | return(__regProcessStackPointer); 119 | } 120 | 121 | 122 | /** \brief Set Process Stack Pointer 123 | 124 | This function assigns the given value to the Process Stack Pointer (PSP). 125 | 126 | \param [in] topOfProcStack Process Stack Pointer value to set 127 | */ 128 | static __INLINE void __set_PSP(uint32_t topOfProcStack) 129 | { 130 | register uint32_t __regProcessStackPointer __ASM("psp"); 131 | __regProcessStackPointer = topOfProcStack; 132 | } 133 | 134 | 135 | /** \brief Get Main Stack Pointer 136 | 137 | This function returns the current value of the Main Stack Pointer (MSP). 138 | 139 | \return MSP Register value 140 | */ 141 | static __INLINE uint32_t __get_MSP(void) 142 | { 143 | register uint32_t __regMainStackPointer __ASM("msp"); 144 | return(__regMainStackPointer); 145 | } 146 | 147 | 148 | /** \brief Set Main Stack Pointer 149 | 150 | This function assigns the given value to the Main Stack Pointer (MSP). 151 | 152 | \param [in] topOfMainStack Main Stack Pointer value to set 153 | */ 154 | static __INLINE void __set_MSP(uint32_t topOfMainStack) 155 | { 156 | register uint32_t __regMainStackPointer __ASM("msp"); 157 | __regMainStackPointer = topOfMainStack; 158 | } 159 | 160 | 161 | /** \brief Get Priority Mask 162 | 163 | This function returns the current state of the priority mask bit from the Priority Mask Register. 164 | 165 | \return Priority Mask value 166 | */ 167 | static __INLINE uint32_t __get_PRIMASK(void) 168 | { 169 | register uint32_t __regPriMask __ASM("primask"); 170 | return(__regPriMask); 171 | } 172 | 173 | 174 | /** \brief Set Priority Mask 175 | 176 | This function assigns the given value to the Priority Mask Register. 177 | 178 | \param [in] priMask Priority Mask 179 | */ 180 | static __INLINE void __set_PRIMASK(uint32_t priMask) 181 | { 182 | register uint32_t __regPriMask __ASM("primask"); 183 | __regPriMask = (priMask); 184 | } 185 | 186 | 187 | #if (__CORTEX_M >= 0x03) 188 | 189 | /** \brief Enable FIQ 190 | 191 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 192 | Can only be executed in Privileged modes. 193 | */ 194 | #define __enable_fault_irq __enable_fiq 195 | 196 | 197 | /** \brief Disable FIQ 198 | 199 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 200 | Can only be executed in Privileged modes. 201 | */ 202 | #define __disable_fault_irq __disable_fiq 203 | 204 | 205 | /** \brief Get Base Priority 206 | 207 | This function returns the current value of the Base Priority register. 208 | 209 | \return Base Priority register value 210 | */ 211 | static __INLINE uint32_t __get_BASEPRI(void) 212 | { 213 | register uint32_t __regBasePri __ASM("basepri"); 214 | return(__regBasePri); 215 | } 216 | 217 | 218 | /** \brief Set Base Priority 219 | 220 | This function assigns the given value to the Base Priority register. 221 | 222 | \param [in] basePri Base Priority value to set 223 | */ 224 | static __INLINE void __set_BASEPRI(uint32_t basePri) 225 | { 226 | register uint32_t __regBasePri __ASM("basepri"); 227 | __regBasePri = (basePri & 0xff); 228 | } 229 | 230 | 231 | /** \brief Get Fault Mask 232 | 233 | This function returns the current value of the Fault Mask register. 234 | 235 | \return Fault Mask register value 236 | */ 237 | static __INLINE uint32_t __get_FAULTMASK(void) 238 | { 239 | register uint32_t __regFaultMask __ASM("faultmask"); 240 | return(__regFaultMask); 241 | } 242 | 243 | 244 | /** \brief Set Fault Mask 245 | 246 | This function assigns the given value to the Fault Mask register. 247 | 248 | \param [in] faultMask Fault Mask value to set 249 | */ 250 | static __INLINE void __set_FAULTMASK(uint32_t faultMask) 251 | { 252 | register uint32_t __regFaultMask __ASM("faultmask"); 253 | __regFaultMask = (faultMask & (uint32_t)1); 254 | } 255 | 256 | #endif /* (__CORTEX_M >= 0x03) */ 257 | 258 | 259 | #if (__CORTEX_M == 0x04) 260 | 261 | /** \brief Get FPSCR 262 | 263 | This function returns the current value of the Floating Point Status/Control register. 264 | 265 | \return Floating Point Status/Control register value 266 | */ 267 | static __INLINE uint32_t __get_FPSCR(void) 268 | { 269 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 270 | register uint32_t __regfpscr __ASM("fpscr"); 271 | return(__regfpscr); 272 | #else 273 | return(0); 274 | #endif 275 | } 276 | 277 | 278 | /** \brief Set FPSCR 279 | 280 | This function assigns the given value to the Floating Point Status/Control register. 281 | 282 | \param [in] fpscr Floating Point Status/Control value to set 283 | */ 284 | static __INLINE void __set_FPSCR(uint32_t fpscr) 285 | { 286 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 287 | register uint32_t __regfpscr __ASM("fpscr"); 288 | __regfpscr = (fpscr); 289 | #endif 290 | } 291 | 292 | #endif /* (__CORTEX_M == 0x04) */ 293 | 294 | 295 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 296 | /* IAR iccarm specific functions */ 297 | 298 | #include 299 | 300 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 301 | /* GNU gcc specific functions */ 302 | 303 | /** \brief Enable IRQ Interrupts 304 | 305 | This function enables IRQ interrupts by clearing the I-bit in the CPSR. 306 | Can only be executed in Privileged modes. 307 | */ 308 | __attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void) 309 | { 310 | __ASM volatile ("cpsie i"); 311 | } 312 | 313 | 314 | /** \brief Disable IRQ Interrupts 315 | 316 | This function disables IRQ interrupts by setting the I-bit in the CPSR. 317 | Can only be executed in Privileged modes. 318 | */ 319 | __attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void) 320 | { 321 | __ASM volatile ("cpsid i"); 322 | } 323 | 324 | 325 | /** \brief Get Control Register 326 | 327 | This function returns the content of the Control Register. 328 | 329 | \return Control Register value 330 | */ 331 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void) 332 | { 333 | uint32_t result; 334 | 335 | __ASM volatile ("MRS %0, control" : "=r" (result) ); 336 | return(result); 337 | } 338 | 339 | 340 | /** \brief Set Control Register 341 | 342 | This function writes the given value to the Control Register. 343 | 344 | \param [in] control Control Register value to set 345 | */ 346 | __attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control) 347 | { 348 | __ASM volatile ("MSR control, %0" : : "r" (control) ); 349 | } 350 | 351 | 352 | /** \brief Get ISPR Register 353 | 354 | This function returns the content of the ISPR Register. 355 | 356 | \return ISPR Register value 357 | */ 358 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void) 359 | { 360 | uint32_t result; 361 | 362 | __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); 363 | return(result); 364 | } 365 | 366 | 367 | /** \brief Get APSR Register 368 | 369 | This function returns the content of the APSR Register. 370 | 371 | \return APSR Register value 372 | */ 373 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void) 374 | { 375 | uint32_t result; 376 | 377 | __ASM volatile ("MRS %0, apsr" : "=r" (result) ); 378 | return(result); 379 | } 380 | 381 | 382 | /** \brief Get xPSR Register 383 | 384 | This function returns the content of the xPSR Register. 385 | 386 | \return xPSR Register value 387 | */ 388 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void) 389 | { 390 | uint32_t result; 391 | 392 | __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); 393 | return(result); 394 | } 395 | 396 | 397 | /** \brief Get Process Stack Pointer 398 | 399 | This function returns the current value of the Process Stack Pointer (PSP). 400 | 401 | \return PSP Register value 402 | */ 403 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void) 404 | { 405 | register uint32_t result; 406 | 407 | __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); 408 | return(result); 409 | } 410 | 411 | 412 | /** \brief Set Process Stack Pointer 413 | 414 | This function assigns the given value to the Process Stack Pointer (PSP). 415 | 416 | \param [in] topOfProcStack Process Stack Pointer value to set 417 | */ 418 | __attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack) 419 | { 420 | __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); 421 | } 422 | 423 | 424 | /** \brief Get Main Stack Pointer 425 | 426 | This function returns the current value of the Main Stack Pointer (MSP). 427 | 428 | \return MSP Register value 429 | */ 430 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void) 431 | { 432 | register uint32_t result; 433 | 434 | __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); 435 | return(result); 436 | } 437 | 438 | 439 | /** \brief Set Main Stack Pointer 440 | 441 | This function assigns the given value to the Main Stack Pointer (MSP). 442 | 443 | \param [in] topOfMainStack Main Stack Pointer value to set 444 | */ 445 | __attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack) 446 | { 447 | __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); 448 | } 449 | 450 | 451 | /** \brief Get Priority Mask 452 | 453 | This function returns the current state of the priority mask bit from the Priority Mask Register. 454 | 455 | \return Priority Mask value 456 | */ 457 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void) 458 | { 459 | uint32_t result; 460 | 461 | __ASM volatile ("MRS %0, primask" : "=r" (result) ); 462 | return(result); 463 | } 464 | 465 | 466 | /** \brief Set Priority Mask 467 | 468 | This function assigns the given value to the Priority Mask Register. 469 | 470 | \param [in] priMask Priority Mask 471 | */ 472 | __attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask) 473 | { 474 | __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); 475 | } 476 | 477 | 478 | #if (__CORTEX_M >= 0x03) 479 | 480 | /** \brief Enable FIQ 481 | 482 | This function enables FIQ interrupts by clearing the F-bit in the CPSR. 483 | Can only be executed in Privileged modes. 484 | */ 485 | __attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void) 486 | { 487 | __ASM volatile ("cpsie f"); 488 | } 489 | 490 | 491 | /** \brief Disable FIQ 492 | 493 | This function disables FIQ interrupts by setting the F-bit in the CPSR. 494 | Can only be executed in Privileged modes. 495 | */ 496 | __attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void) 497 | { 498 | __ASM volatile ("cpsid f"); 499 | } 500 | 501 | 502 | /** \brief Get Base Priority 503 | 504 | This function returns the current value of the Base Priority register. 505 | 506 | \return Base Priority register value 507 | */ 508 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void) 509 | { 510 | uint32_t result; 511 | 512 | __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); 513 | return(result); 514 | } 515 | 516 | 517 | /** \brief Set Base Priority 518 | 519 | This function assigns the given value to the Base Priority register. 520 | 521 | \param [in] basePri Base Priority value to set 522 | */ 523 | __attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value) 524 | { 525 | __ASM volatile ("MSR basepri, %0" : : "r" (value) ); 526 | } 527 | 528 | 529 | /** \brief Get Fault Mask 530 | 531 | This function returns the current value of the Fault Mask register. 532 | 533 | \return Fault Mask register value 534 | */ 535 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void) 536 | { 537 | uint32_t result; 538 | 539 | __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); 540 | return(result); 541 | } 542 | 543 | 544 | /** \brief Set Fault Mask 545 | 546 | This function assigns the given value to the Fault Mask register. 547 | 548 | \param [in] faultMask Fault Mask value to set 549 | */ 550 | __attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask) 551 | { 552 | __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); 553 | } 554 | 555 | #endif /* (__CORTEX_M >= 0x03) */ 556 | 557 | 558 | #if (__CORTEX_M == 0x04) 559 | 560 | /** \brief Get FPSCR 561 | 562 | This function returns the current value of the Floating Point Status/Control register. 563 | 564 | \return Floating Point Status/Control register value 565 | */ 566 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void) 567 | { 568 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 569 | uint32_t result; 570 | 571 | __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); 572 | return(result); 573 | #else 574 | return(0); 575 | #endif 576 | } 577 | 578 | 579 | /** \brief Set FPSCR 580 | 581 | This function assigns the given value to the Floating Point Status/Control register. 582 | 583 | \param [in] fpscr Floating Point Status/Control value to set 584 | */ 585 | __attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr) 586 | { 587 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 588 | __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); 589 | #endif 590 | } 591 | 592 | #endif /* (__CORTEX_M == 0x04) */ 593 | 594 | 595 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 596 | /* TASKING carm specific functions */ 597 | 598 | /* 599 | * The CMSIS functions have been implemented as intrinsics in the compiler. 600 | * Please use "carm -?i" to get an up to date list of all instrinsics, 601 | * Including the CMSIS ones. 602 | */ 603 | 604 | #endif 605 | 606 | /*@} end of CMSIS_Core_RegAccFunctions */ 607 | 608 | 609 | #endif /* __CORE_CMFUNC_H */ 610 | -------------------------------------------------------------------------------- /sys/inc/core/core_cmInstr.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************//** 2 | * @file core_cmInstr.h 3 | * @brief CMSIS Cortex-M Core Instruction Access Header File 4 | * @version V2.10 5 | * @date 19. July 2011 6 | * 7 | * @note 8 | * Copyright (C) 2009-2011 ARM Limited. All rights reserved. 9 | * 10 | * @par 11 | * ARM Limited (ARM) is supplying this software for use with Cortex-M 12 | * processor based microcontrollers. This file can be freely distributed 13 | * within development tools that are supporting such ARM based processors. 14 | * 15 | * @par 16 | * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED 17 | * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF 18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. 19 | * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR 20 | * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. 21 | * 22 | ******************************************************************************/ 23 | 24 | #ifndef __CORE_CMINSTR_H 25 | #define __CORE_CMINSTR_H 26 | 27 | 28 | /* ########################## Core Instruction Access ######################### */ 29 | /** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface 30 | Access to dedicated instructions 31 | @{ 32 | */ 33 | 34 | #if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ 35 | /* ARM armcc specific functions */ 36 | 37 | #if (__ARMCC_VERSION < 400677) 38 | #error "Please use ARM Compiler Toolchain V4.0.677 or later!" 39 | #endif 40 | 41 | 42 | /** \brief No Operation 43 | 44 | No Operation does nothing. This instruction can be used for code alignment purposes. 45 | */ 46 | #define __NOP __nop 47 | 48 | 49 | /** \brief Wait For Interrupt 50 | 51 | Wait For Interrupt is a hint instruction that suspends execution 52 | until one of a number of events occurs. 53 | */ 54 | #define __WFI __wfi 55 | 56 | 57 | /** \brief Wait For Event 58 | 59 | Wait For Event is a hint instruction that permits the processor to enter 60 | a low-power state until one of a number of events occurs. 61 | */ 62 | #define __WFE __wfe 63 | 64 | 65 | /** \brief Send Event 66 | 67 | Send Event is a hint instruction. It causes an event to be signaled to the CPU. 68 | */ 69 | #define __SEV __sev 70 | 71 | 72 | /** \brief Instruction Synchronization Barrier 73 | 74 | Instruction Synchronization Barrier flushes the pipeline in the processor, 75 | so that all instructions following the ISB are fetched from cache or 76 | memory, after the instruction has been completed. 77 | */ 78 | #define __ISB() __isb(0xF) 79 | 80 | 81 | /** \brief Data Synchronization Barrier 82 | 83 | This function acts as a special kind of Data Memory Barrier. 84 | It completes when all explicit memory accesses before this instruction complete. 85 | */ 86 | #define __DSB() __dsb(0xF) 87 | 88 | 89 | /** \brief Data Memory Barrier 90 | 91 | This function ensures the apparent order of the explicit memory operations before 92 | and after the instruction, without ensuring their completion. 93 | */ 94 | #define __DMB() __dmb(0xF) 95 | 96 | 97 | /** \brief Reverse byte order (32 bit) 98 | 99 | This function reverses the byte order in integer value. 100 | 101 | \param [in] value Value to reverse 102 | \return Reversed value 103 | */ 104 | #define __REV __rev 105 | 106 | 107 | /** \brief Reverse byte order (16 bit) 108 | 109 | This function reverses the byte order in two unsigned short values. 110 | 111 | \param [in] value Value to reverse 112 | \return Reversed value 113 | */ 114 | static __INLINE __ASM uint32_t __REV16(uint32_t value) 115 | { 116 | rev16 r0, r0 117 | bx lr 118 | } 119 | 120 | 121 | /** \brief Reverse byte order in signed short value 122 | 123 | This function reverses the byte order in a signed short value with sign extension to integer. 124 | 125 | \param [in] value Value to reverse 126 | \return Reversed value 127 | */ 128 | static __INLINE __ASM int32_t __REVSH(int32_t value) 129 | { 130 | revsh r0, r0 131 | bx lr 132 | } 133 | 134 | 135 | #if (__CORTEX_M >= 0x03) 136 | 137 | /** \brief Reverse bit order of value 138 | 139 | This function reverses the bit order of the given value. 140 | 141 | \param [in] value Value to reverse 142 | \return Reversed value 143 | */ 144 | #define __RBIT __rbit 145 | 146 | 147 | /** \brief LDR Exclusive (8 bit) 148 | 149 | This function performs a exclusive LDR command for 8 bit value. 150 | 151 | \param [in] ptr Pointer to data 152 | \return value of type uint8_t at (*ptr) 153 | */ 154 | #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) 155 | 156 | 157 | /** \brief LDR Exclusive (16 bit) 158 | 159 | This function performs a exclusive LDR command for 16 bit values. 160 | 161 | \param [in] ptr Pointer to data 162 | \return value of type uint16_t at (*ptr) 163 | */ 164 | #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) 165 | 166 | 167 | /** \brief LDR Exclusive (32 bit) 168 | 169 | This function performs a exclusive LDR command for 32 bit values. 170 | 171 | \param [in] ptr Pointer to data 172 | \return value of type uint32_t at (*ptr) 173 | */ 174 | #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) 175 | 176 | 177 | /** \brief STR Exclusive (8 bit) 178 | 179 | This function performs a exclusive STR command for 8 bit values. 180 | 181 | \param [in] value Value to store 182 | \param [in] ptr Pointer to location 183 | \return 0 Function succeeded 184 | \return 1 Function failed 185 | */ 186 | #define __STREXB(value, ptr) __strex(value, ptr) 187 | 188 | 189 | /** \brief STR Exclusive (16 bit) 190 | 191 | This function performs a exclusive STR command for 16 bit values. 192 | 193 | \param [in] value Value to store 194 | \param [in] ptr Pointer to location 195 | \return 0 Function succeeded 196 | \return 1 Function failed 197 | */ 198 | #define __STREXH(value, ptr) __strex(value, ptr) 199 | 200 | 201 | /** \brief STR Exclusive (32 bit) 202 | 203 | This function performs a exclusive STR command for 32 bit values. 204 | 205 | \param [in] value Value to store 206 | \param [in] ptr Pointer to location 207 | \return 0 Function succeeded 208 | \return 1 Function failed 209 | */ 210 | #define __STREXW(value, ptr) __strex(value, ptr) 211 | 212 | 213 | /** \brief Remove the exclusive lock 214 | 215 | This function removes the exclusive lock which is created by LDREX. 216 | 217 | */ 218 | #define __CLREX __clrex 219 | 220 | 221 | /** \brief Signed Saturate 222 | 223 | This function saturates a signed value. 224 | 225 | \param [in] value Value to be saturated 226 | \param [in] sat Bit position to saturate to (1..32) 227 | \return Saturated value 228 | */ 229 | #define __SSAT __ssat 230 | 231 | 232 | /** \brief Unsigned Saturate 233 | 234 | This function saturates an unsigned value. 235 | 236 | \param [in] value Value to be saturated 237 | \param [in] sat Bit position to saturate to (0..31) 238 | \return Saturated value 239 | */ 240 | #define __USAT __usat 241 | 242 | 243 | /** \brief Count leading zeros 244 | 245 | This function counts the number of leading zeros of a data value. 246 | 247 | \param [in] value Value to count the leading zeros 248 | \return number of leading zeros in value 249 | */ 250 | #define __CLZ __clz 251 | 252 | #endif /* (__CORTEX_M >= 0x03) */ 253 | 254 | 255 | 256 | #elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ 257 | /* IAR iccarm specific functions */ 258 | 259 | #include 260 | 261 | 262 | #elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ 263 | /* GNU gcc specific functions */ 264 | 265 | /** \brief No Operation 266 | 267 | No Operation does nothing. This instruction can be used for code alignment purposes. 268 | */ 269 | __attribute__( ( always_inline ) ) static __INLINE void __NOP(void) 270 | { 271 | __ASM volatile ("nop"); 272 | } 273 | 274 | 275 | /** \brief Wait For Interrupt 276 | 277 | Wait For Interrupt is a hint instruction that suspends execution 278 | until one of a number of events occurs. 279 | */ 280 | __attribute__( ( always_inline ) ) static __INLINE void __WFI(void) 281 | { 282 | __ASM volatile ("wfi"); 283 | } 284 | 285 | 286 | /** \brief Wait For Event 287 | 288 | Wait For Event is a hint instruction that permits the processor to enter 289 | a low-power state until one of a number of events occurs. 290 | */ 291 | __attribute__( ( always_inline ) ) static __INLINE void __WFE(void) 292 | { 293 | __ASM volatile ("wfe"); 294 | } 295 | 296 | 297 | /** \brief Send Event 298 | 299 | Send Event is a hint instruction. It causes an event to be signaled to the CPU. 300 | */ 301 | __attribute__( ( always_inline ) ) static __INLINE void __SEV(void) 302 | { 303 | __ASM volatile ("sev"); 304 | } 305 | 306 | 307 | /** \brief Instruction Synchronization Barrier 308 | 309 | Instruction Synchronization Barrier flushes the pipeline in the processor, 310 | so that all instructions following the ISB are fetched from cache or 311 | memory, after the instruction has been completed. 312 | */ 313 | __attribute__( ( always_inline ) ) static __INLINE void __ISB(void) 314 | { 315 | __ASM volatile ("isb"); 316 | } 317 | 318 | 319 | /** \brief Data Synchronization Barrier 320 | 321 | This function acts as a special kind of Data Memory Barrier. 322 | It completes when all explicit memory accesses before this instruction complete. 323 | */ 324 | __attribute__( ( always_inline ) ) static __INLINE void __DSB(void) 325 | { 326 | __ASM volatile ("dsb"); 327 | } 328 | 329 | 330 | /** \brief Data Memory Barrier 331 | 332 | This function ensures the apparent order of the explicit memory operations before 333 | and after the instruction, without ensuring their completion. 334 | */ 335 | __attribute__( ( always_inline ) ) static __INLINE void __DMB(void) 336 | { 337 | __ASM volatile ("dmb"); 338 | } 339 | 340 | 341 | /** \brief Reverse byte order (32 bit) 342 | 343 | This function reverses the byte order in integer value. 344 | 345 | \param [in] value Value to reverse 346 | \return Reversed value 347 | */ 348 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value) 349 | { 350 | uint32_t result; 351 | 352 | __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); 353 | return(result); 354 | } 355 | 356 | 357 | /** \brief Reverse byte order (16 bit) 358 | 359 | This function reverses the byte order in two unsigned short values. 360 | 361 | \param [in] value Value to reverse 362 | \return Reversed value 363 | */ 364 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value) 365 | { 366 | uint32_t result; 367 | 368 | __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); 369 | return(result); 370 | } 371 | 372 | 373 | /** \brief Reverse byte order in signed short value 374 | 375 | This function reverses the byte order in a signed short value with sign extension to integer. 376 | 377 | \param [in] value Value to reverse 378 | \return Reversed value 379 | */ 380 | __attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value) 381 | { 382 | uint32_t result; 383 | 384 | __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); 385 | return(result); 386 | } 387 | 388 | 389 | #if (__CORTEX_M >= 0x03) 390 | 391 | /** \brief Reverse bit order of value 392 | 393 | This function reverses the bit order of the given value. 394 | 395 | \param [in] value Value to reverse 396 | \return Reversed value 397 | */ 398 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value) 399 | { 400 | uint32_t result; 401 | 402 | __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); 403 | return(result); 404 | } 405 | 406 | 407 | /** \brief LDR Exclusive (8 bit) 408 | 409 | This function performs a exclusive LDR command for 8 bit value. 410 | 411 | \param [in] ptr Pointer to data 412 | \return value of type uint8_t at (*ptr) 413 | */ 414 | __attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr) 415 | { 416 | uint8_t result; 417 | 418 | __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); 419 | return(result); 420 | } 421 | 422 | 423 | /** \brief LDR Exclusive (16 bit) 424 | 425 | This function performs a exclusive LDR command for 16 bit values. 426 | 427 | \param [in] ptr Pointer to data 428 | \return value of type uint16_t at (*ptr) 429 | */ 430 | __attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr) 431 | { 432 | uint16_t result; 433 | 434 | __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); 435 | return(result); 436 | } 437 | 438 | 439 | /** \brief LDR Exclusive (32 bit) 440 | 441 | This function performs a exclusive LDR command for 32 bit values. 442 | 443 | \param [in] ptr Pointer to data 444 | \return value of type uint32_t at (*ptr) 445 | */ 446 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr) 447 | { 448 | uint32_t result; 449 | 450 | __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); 451 | return(result); 452 | } 453 | 454 | 455 | /** \brief STR Exclusive (8 bit) 456 | 457 | This function performs a exclusive STR command for 8 bit values. 458 | 459 | \param [in] value Value to store 460 | \param [in] ptr Pointer to location 461 | \return 0 Function succeeded 462 | \return 1 Function failed 463 | */ 464 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) 465 | { 466 | uint32_t result; 467 | 468 | __ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); 469 | return(result); 470 | } 471 | 472 | 473 | /** \brief STR Exclusive (16 bit) 474 | 475 | This function performs a exclusive STR command for 16 bit values. 476 | 477 | \param [in] value Value to store 478 | \param [in] ptr Pointer to location 479 | \return 0 Function succeeded 480 | \return 1 Function failed 481 | */ 482 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) 483 | { 484 | uint32_t result; 485 | 486 | __ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); 487 | return(result); 488 | } 489 | 490 | 491 | /** \brief STR Exclusive (32 bit) 492 | 493 | This function performs a exclusive STR command for 32 bit values. 494 | 495 | \param [in] value Value to store 496 | \param [in] ptr Pointer to location 497 | \return 0 Function succeeded 498 | \return 1 Function failed 499 | */ 500 | __attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) 501 | { 502 | uint32_t result; 503 | 504 | __ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) ); 505 | return(result); 506 | } 507 | 508 | 509 | /** \brief Remove the exclusive lock 510 | 511 | This function removes the exclusive lock which is created by LDREX. 512 | 513 | */ 514 | __attribute__( ( always_inline ) ) static __INLINE void __CLREX(void) 515 | { 516 | __ASM volatile ("clrex"); 517 | } 518 | 519 | 520 | /** \brief Signed Saturate 521 | 522 | This function saturates a signed value. 523 | 524 | \param [in] value Value to be saturated 525 | \param [in] sat Bit position to saturate to (1..32) 526 | \return Saturated value 527 | */ 528 | #define __SSAT(ARG1,ARG2) \ 529 | ({ \ 530 | uint32_t __RES, __ARG1 = (ARG1); \ 531 | __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 532 | __RES; \ 533 | }) 534 | 535 | 536 | /** \brief Unsigned Saturate 537 | 538 | This function saturates an unsigned value. 539 | 540 | \param [in] value Value to be saturated 541 | \param [in] sat Bit position to saturate to (0..31) 542 | \return Saturated value 543 | */ 544 | #define __USAT(ARG1,ARG2) \ 545 | ({ \ 546 | uint32_t __RES, __ARG1 = (ARG1); \ 547 | __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ 548 | __RES; \ 549 | }) 550 | 551 | 552 | /** \brief Count leading zeros 553 | 554 | This function counts the number of leading zeros of a data value. 555 | 556 | \param [in] value Value to count the leading zeros 557 | \return number of leading zeros in value 558 | */ 559 | __attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value) 560 | { 561 | uint8_t result; 562 | 563 | __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); 564 | return(result); 565 | } 566 | 567 | #endif /* (__CORTEX_M >= 0x03) */ 568 | 569 | 570 | 571 | 572 | #elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ 573 | /* TASKING carm specific functions */ 574 | 575 | /* 576 | * The CMSIS functions have been implemented as intrinsics in the compiler. 577 | * Please use "carm -?i" to get an up to date list of all intrinsics, 578 | * Including the CMSIS ones. 579 | */ 580 | 581 | #endif 582 | 583 | /*@}*/ /* end of group CMSIS_Core_InstructionInterface */ 584 | 585 | #endif /* __CORE_CMINSTR_H */ 586 | -------------------------------------------------------------------------------- /sys/inc/stm32f4xx.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neykov/armboot/5324542d5ea1a0720020c6b06e24525a4bd355ac/sys/inc/stm32f4xx.h -------------------------------------------------------------------------------- /sys/inc/system_stm32f4xx.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f4xx.h 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 30-September-2011 7 | * @brief CMSIS Cortex-M4 Device System Source File for STM32F4xx devices. 8 | ****************************************************************************** 9 | * @attention 10 | * 11 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 12 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 13 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 14 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 15 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 16 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 17 | * 18 | *

© COPYRIGHT 2011 STMicroelectronics

19 | ****************************************************************************** 20 | */ 21 | 22 | /** @addtogroup CMSIS 23 | * @{ 24 | */ 25 | 26 | /** @addtogroup stm32f4xx_system 27 | * @{ 28 | */ 29 | 30 | /** 31 | * @brief Define to prevent recursive inclusion 32 | */ 33 | #ifndef __SYSTEM_STM32F4XX_H 34 | #define __SYSTEM_STM32F4XX_H 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | /** @addtogroup STM32F4xx_System_Includes 41 | * @{ 42 | */ 43 | 44 | /** 45 | * @} 46 | */ 47 | 48 | 49 | /** @addtogroup STM32F4xx_System_Exported_types 50 | * @{ 51 | */ 52 | 53 | extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ 54 | 55 | 56 | /** 57 | * @} 58 | */ 59 | 60 | /** @addtogroup STM32F4xx_System_Exported_Constants 61 | * @{ 62 | */ 63 | 64 | /** 65 | * @} 66 | */ 67 | 68 | /** @addtogroup STM32F4xx_System_Exported_Macros 69 | * @{ 70 | */ 71 | 72 | /** 73 | * @} 74 | */ 75 | 76 | /** @addtogroup STM32F4xx_System_Exported_Functions 77 | * @{ 78 | */ 79 | 80 | extern void SystemInit(void); 81 | extern void SystemCoreClockUpdate(void); 82 | /** 83 | * @} 84 | */ 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /*__SYSTEM_STM32F4XX_H */ 91 | 92 | /** 93 | * @} 94 | */ 95 | 96 | /** 97 | * @} 98 | */ 99 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 100 | -------------------------------------------------------------------------------- /sys/startup_stm32f4xx.s: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file startup_stm32f4xx.s 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 30-September-2011 7 | * @brief STM32F4xx Devices vector table for Atollic TrueSTUDIO toolchain. 8 | * This module performs: 9 | * - Set the initial SP 10 | * - Set the initial PC == Reset_Handler, 11 | * - Set the vector table entries with the exceptions ISR address 12 | * - Configure the clock system and the external SRAM mounted on 13 | * STM324xG-EVAL board to be used as data memory (optional, 14 | * to be enabled by user) 15 | * - Branches to main in the C library (which eventually 16 | * calls main()). 17 | * After Reset the Cortex-M4 processor is in Thread mode, 18 | * priority is Privileged, and the Stack is set to Main. 19 | ****************************************************************************** 20 | * @attention 21 | * 22 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 23 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 24 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 25 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 26 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 27 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 28 | * 29 | *

© COPYRIGHT 2011 STMicroelectronics

30 | ****************************************************************************** 31 | */ 32 | 33 | .syntax unified 34 | .cpu cortex-m3 35 | .fpu softvfp 36 | .thumb 37 | 38 | .global g_pfnVectors 39 | .global Default_Handler 40 | 41 | /* start address for the initialization values of the .data section. 42 | defined in linker script */ 43 | .word _sidata 44 | /* start address for the .data section. defined in linker script */ 45 | .word _sdata 46 | /* end address for the .data section. defined in linker script */ 47 | .word _edata 48 | /* start address for the .bss section. defined in linker script */ 49 | .word _sbss 50 | /* end address for the .bss section. defined in linker script */ 51 | .word _ebss 52 | /* stack used for SystemInit_ExtMemCtl; always internal RAM used */ 53 | 54 | /** 55 | * @brief This is the code that gets called when the processor first 56 | * starts execution following a reset event. Only the absolutely 57 | * necessary set is performed, after which the application 58 | * supplied main() routine is called. 59 | * @param None 60 | * @retval : None 61 | */ 62 | 63 | .section .text.Reset_Handler 64 | .weak Reset_Handler 65 | .type Reset_Handler, %function 66 | Reset_Handler: 67 | 68 | /* Copy the data segment initializers from flash to SRAM */ 69 | movs r1, #0 70 | b LoopCopyDataInit 71 | 72 | CopyDataInit: 73 | ldr r3, =_sidata 74 | ldr r3, [r3, r1] 75 | str r3, [r0, r1] 76 | adds r1, r1, #4 77 | 78 | LoopCopyDataInit: 79 | ldr r0, =_sdata 80 | ldr r3, =_edata 81 | adds r2, r0, r1 82 | cmp r2, r3 83 | bcc CopyDataInit 84 | ldr r2, =_sbss 85 | b LoopFillZerobss 86 | /* Zero fill the bss segment. */ 87 | FillZerobss: 88 | movs r3, #0 89 | str r3, [r2], #4 90 | 91 | LoopFillZerobss: 92 | ldr r3, = _ebss 93 | cmp r2, r3 94 | bcc FillZerobss 95 | 96 | /* Call the clock system intitialization function.*/ 97 | bl SystemInit 98 | /* Call static constructors */ 99 | bl __libc_init_array 100 | /* Call the application's entry point.*/ 101 | bl main 102 | bx lr 103 | .size Reset_Handler, .-Reset_Handler 104 | 105 | /** 106 | * @brief This is the code that gets called when the processor receives an 107 | * unexpected interrupt. This simply enters an infinite loop, preserving 108 | * the system state for examination by a debugger. 109 | * @param None 110 | * @retval None 111 | */ 112 | .section .text.Default_Handler,"ax",%progbits 113 | Default_Handler: 114 | Infinite_Loop: 115 | b Infinite_Loop 116 | .size Default_Handler, .-Default_Handler 117 | /****************************************************************************** 118 | * 119 | * The minimal vector table for a Cortex M3. Note that the proper constructs 120 | * must be placed on this to ensure that it ends up at physical address 121 | * 0x0000.0000. 122 | * 123 | *******************************************************************************/ 124 | .section .isr_vector,"a",%progbits 125 | .type g_pfnVectors, %object 126 | .size g_pfnVectors, .-g_pfnVectors 127 | 128 | 129 | g_pfnVectors: 130 | .word _estack 131 | .word Reset_Handler 132 | .word NMI_Handler 133 | .word HardFault_Handler 134 | .word MemManage_Handler 135 | .word BusFault_Handler 136 | .word UsageFault_Handler 137 | .word 0 138 | .word 0 139 | .word 0 140 | .word 0 141 | .word SVC_Handler 142 | .word DebugMon_Handler 143 | .word 0 144 | .word PendSV_Handler 145 | .word SysTick_Handler 146 | 147 | /* External Interrupts */ 148 | .word WWDG_IRQHandler /* Window WatchDog */ 149 | .word PVD_IRQHandler /* PVD through EXTI Line detection */ 150 | .word TAMP_STAMP_IRQHandler /* Tamper and TimeStamps through the EXTI line */ 151 | .word RTC_WKUP_IRQHandler /* RTC Wakeup through the EXTI line */ 152 | .word FLASH_IRQHandler /* FLASH */ 153 | .word RCC_IRQHandler /* RCC */ 154 | .word EXTI0_IRQHandler /* EXTI Line0 */ 155 | .word EXTI1_IRQHandler /* EXTI Line1 */ 156 | .word EXTI2_IRQHandler /* EXTI Line2 */ 157 | .word EXTI3_IRQHandler /* EXTI Line3 */ 158 | .word EXTI4_IRQHandler /* EXTI Line4 */ 159 | .word DMA1_Stream0_IRQHandler /* DMA1 Stream 0 */ 160 | .word DMA1_Stream1_IRQHandler /* DMA1 Stream 1 */ 161 | .word DMA1_Stream2_IRQHandler /* DMA1 Stream 2 */ 162 | .word DMA1_Stream3_IRQHandler /* DMA1 Stream 3 */ 163 | .word DMA1_Stream4_IRQHandler /* DMA1 Stream 4 */ 164 | .word DMA1_Stream5_IRQHandler /* DMA1 Stream 5 */ 165 | .word DMA1_Stream6_IRQHandler /* DMA1 Stream 6 */ 166 | .word ADC_IRQHandler /* ADC1, ADC2 and ADC3s */ 167 | .word CAN1_TX_IRQHandler /* CAN1 TX */ 168 | .word CAN1_RX0_IRQHandler /* CAN1 RX0 */ 169 | .word CAN1_RX1_IRQHandler /* CAN1 RX1 */ 170 | .word CAN1_SCE_IRQHandler /* CAN1 SCE */ 171 | .word EXTI9_5_IRQHandler /* External Line[9:5]s */ 172 | .word TIM1_BRK_TIM9_IRQHandler /* TIM1 Break and TIM9 */ 173 | .word TIM1_UP_TIM10_IRQHandler /* TIM1 Update and TIM10 */ 174 | .word TIM1_TRG_COM_TIM11_IRQHandler /* TIM1 Trigger and Commutation and TIM11 */ 175 | .word TIM1_CC_IRQHandler /* TIM1 Capture Compare */ 176 | .word TIM2_IRQHandler /* TIM2 */ 177 | .word TIM3_IRQHandler /* TIM3 */ 178 | .word TIM4_IRQHandler /* TIM4 */ 179 | .word I2C1_EV_IRQHandler /* I2C1 Event */ 180 | .word I2C1_ER_IRQHandler /* I2C1 Error */ 181 | .word I2C2_EV_IRQHandler /* I2C2 Event */ 182 | .word I2C2_ER_IRQHandler /* I2C2 Error */ 183 | .word SPI1_IRQHandler /* SPI1 */ 184 | .word SPI2_IRQHandler /* SPI2 */ 185 | .word USART1_IRQHandler /* USART1 */ 186 | .word USART2_IRQHandler /* USART2 */ 187 | .word USART3_IRQHandler /* USART3 */ 188 | .word EXTI15_10_IRQHandler /* External Line[15:10]s */ 189 | .word RTC_Alarm_IRQHandler /* RTC Alarm (A and B) through EXTI Line */ 190 | .word OTG_FS_WKUP_IRQHandler /* USB OTG FS Wakeup through EXTI line */ 191 | .word TIM8_BRK_TIM12_IRQHandler /* TIM8 Break and TIM12 */ 192 | .word TIM8_UP_TIM13_IRQHandler /* TIM8 Update and TIM13 */ 193 | .word TIM8_TRG_COM_TIM14_IRQHandler /* TIM8 Trigger and Commutation and TIM14 */ 194 | .word TIM8_CC_IRQHandler /* TIM8 Capture Compare */ 195 | .word DMA1_Stream7_IRQHandler /* DMA1 Stream7 */ 196 | .word FSMC_IRQHandler /* FSMC */ 197 | .word SDIO_IRQHandler /* SDIO */ 198 | .word TIM5_IRQHandler /* TIM5 */ 199 | .word SPI3_IRQHandler /* SPI3 */ 200 | .word UART4_IRQHandler /* UART4 */ 201 | .word UART5_IRQHandler /* UART5 */ 202 | .word TIM6_DAC_IRQHandler /* TIM6 and DAC1&2 underrun errors */ 203 | .word TIM7_IRQHandler /* TIM7 */ 204 | .word DMA2_Stream0_IRQHandler /* DMA2 Stream 0 */ 205 | .word DMA2_Stream1_IRQHandler /* DMA2 Stream 1 */ 206 | .word DMA2_Stream2_IRQHandler /* DMA2 Stream 2 */ 207 | .word DMA2_Stream3_IRQHandler /* DMA2 Stream 3 */ 208 | .word DMA2_Stream4_IRQHandler /* DMA2 Stream 4 */ 209 | .word ETH_IRQHandler /* Ethernet */ 210 | .word ETH_WKUP_IRQHandler /* Ethernet Wakeup through EXTI line */ 211 | .word CAN2_TX_IRQHandler /* CAN2 TX */ 212 | .word CAN2_RX0_IRQHandler /* CAN2 RX0 */ 213 | .word CAN2_RX1_IRQHandler /* CAN2 RX1 */ 214 | .word CAN2_SCE_IRQHandler /* CAN2 SCE */ 215 | .word OTG_FS_IRQHandler /* USB OTG FS */ 216 | .word DMA2_Stream5_IRQHandler /* DMA2 Stream 5 */ 217 | .word DMA2_Stream6_IRQHandler /* DMA2 Stream 6 */ 218 | .word DMA2_Stream7_IRQHandler /* DMA2 Stream 7 */ 219 | .word USART6_IRQHandler /* USART6 */ 220 | .word I2C3_EV_IRQHandler /* I2C3 event */ 221 | .word I2C3_ER_IRQHandler /* I2C3 error */ 222 | .word OTG_HS_EP1_OUT_IRQHandler /* USB OTG HS End Point 1 Out */ 223 | .word OTG_HS_EP1_IN_IRQHandler /* USB OTG HS End Point 1 In */ 224 | .word OTG_HS_WKUP_IRQHandler /* USB OTG HS Wakeup through EXTI */ 225 | .word OTG_HS_IRQHandler /* USB OTG HS */ 226 | .word DCMI_IRQHandler /* DCMI */ 227 | .word CRYP_IRQHandler /* CRYP crypto */ 228 | .word HASH_RNG_IRQHandler /* Hash and Rng */ 229 | .word FPU_IRQHandler /* FPU */ 230 | 231 | 232 | /******************************************************************************* 233 | * 234 | * Provide weak aliases for each Exception handler to the Default_Handler. 235 | * As they are weak aliases, any function with the same name will override 236 | * this definition. 237 | * 238 | *******************************************************************************/ 239 | .weak NMI_Handler 240 | .thumb_set NMI_Handler,Default_Handler 241 | 242 | .weak HardFault_Handler 243 | .thumb_set HardFault_Handler,Default_Handler 244 | 245 | .weak MemManage_Handler 246 | .thumb_set MemManage_Handler,Default_Handler 247 | 248 | .weak BusFault_Handler 249 | .thumb_set BusFault_Handler,Default_Handler 250 | 251 | .weak UsageFault_Handler 252 | .thumb_set UsageFault_Handler,Default_Handler 253 | 254 | .weak SVC_Handler 255 | .thumb_set SVC_Handler,Default_Handler 256 | 257 | .weak DebugMon_Handler 258 | .thumb_set DebugMon_Handler,Default_Handler 259 | 260 | .weak PendSV_Handler 261 | .thumb_set PendSV_Handler,Default_Handler 262 | 263 | .weak SysTick_Handler 264 | .thumb_set SysTick_Handler,Default_Handler 265 | 266 | .weak WWDG_IRQHandler 267 | .thumb_set WWDG_IRQHandler,Default_Handler 268 | 269 | .weak PVD_IRQHandler 270 | .thumb_set PVD_IRQHandler,Default_Handler 271 | 272 | .weak TAMP_STAMP_IRQHandler 273 | .thumb_set TAMP_STAMP_IRQHandler,Default_Handler 274 | 275 | .weak RTC_WKUP_IRQHandler 276 | .thumb_set RTC_WKUP_IRQHandler,Default_Handler 277 | 278 | .weak FLASH_IRQHandler 279 | .thumb_set FLASH_IRQHandler,Default_Handler 280 | 281 | .weak RCC_IRQHandler 282 | .thumb_set RCC_IRQHandler,Default_Handler 283 | 284 | .weak EXTI0_IRQHandler 285 | .thumb_set EXTI0_IRQHandler,Default_Handler 286 | 287 | .weak EXTI1_IRQHandler 288 | .thumb_set EXTI1_IRQHandler,Default_Handler 289 | 290 | .weak EXTI2_IRQHandler 291 | .thumb_set EXTI2_IRQHandler,Default_Handler 292 | 293 | .weak EXTI3_IRQHandler 294 | .thumb_set EXTI3_IRQHandler,Default_Handler 295 | 296 | .weak EXTI4_IRQHandler 297 | .thumb_set EXTI4_IRQHandler,Default_Handler 298 | 299 | .weak DMA1_Stream0_IRQHandler 300 | .thumb_set DMA1_Stream0_IRQHandler,Default_Handler 301 | 302 | .weak DMA1_Stream1_IRQHandler 303 | .thumb_set DMA1_Stream1_IRQHandler,Default_Handler 304 | 305 | .weak DMA1_Stream2_IRQHandler 306 | .thumb_set DMA1_Stream2_IRQHandler,Default_Handler 307 | 308 | .weak DMA1_Stream3_IRQHandler 309 | .thumb_set DMA1_Stream3_IRQHandler,Default_Handler 310 | 311 | .weak DMA1_Stream4_IRQHandler 312 | .thumb_set DMA1_Stream4_IRQHandler,Default_Handler 313 | 314 | .weak DMA1_Stream5_IRQHandler 315 | .thumb_set DMA1_Stream5_IRQHandler,Default_Handler 316 | 317 | .weak DMA1_Stream6_IRQHandler 318 | .thumb_set DMA1_Stream6_IRQHandler,Default_Handler 319 | 320 | .weak ADC_IRQHandler 321 | .thumb_set ADC_IRQHandler,Default_Handler 322 | 323 | .weak CAN1_TX_IRQHandler 324 | .thumb_set CAN1_TX_IRQHandler,Default_Handler 325 | 326 | .weak CAN1_RX0_IRQHandler 327 | .thumb_set CAN1_RX0_IRQHandler,Default_Handler 328 | 329 | .weak CAN1_RX1_IRQHandler 330 | .thumb_set CAN1_RX1_IRQHandler,Default_Handler 331 | 332 | .weak CAN1_SCE_IRQHandler 333 | .thumb_set CAN1_SCE_IRQHandler,Default_Handler 334 | 335 | .weak EXTI9_5_IRQHandler 336 | .thumb_set EXTI9_5_IRQHandler,Default_Handler 337 | 338 | .weak TIM1_BRK_TIM9_IRQHandler 339 | .thumb_set TIM1_BRK_TIM9_IRQHandler,Default_Handler 340 | 341 | .weak TIM1_UP_TIM10_IRQHandler 342 | .thumb_set TIM1_UP_TIM10_IRQHandler,Default_Handler 343 | 344 | .weak TIM1_TRG_COM_TIM11_IRQHandler 345 | .thumb_set TIM1_TRG_COM_TIM11_IRQHandler,Default_Handler 346 | 347 | .weak TIM1_CC_IRQHandler 348 | .thumb_set TIM1_CC_IRQHandler,Default_Handler 349 | 350 | .weak TIM2_IRQHandler 351 | .thumb_set TIM2_IRQHandler,Default_Handler 352 | 353 | .weak TIM3_IRQHandler 354 | .thumb_set TIM3_IRQHandler,Default_Handler 355 | 356 | .weak TIM4_IRQHandler 357 | .thumb_set TIM4_IRQHandler,Default_Handler 358 | 359 | .weak I2C1_EV_IRQHandler 360 | .thumb_set I2C1_EV_IRQHandler,Default_Handler 361 | 362 | .weak I2C1_ER_IRQHandler 363 | .thumb_set I2C1_ER_IRQHandler,Default_Handler 364 | 365 | .weak I2C2_EV_IRQHandler 366 | .thumb_set I2C2_EV_IRQHandler,Default_Handler 367 | 368 | .weak I2C2_ER_IRQHandler 369 | .thumb_set I2C2_ER_IRQHandler,Default_Handler 370 | 371 | .weak SPI1_IRQHandler 372 | .thumb_set SPI1_IRQHandler,Default_Handler 373 | 374 | .weak SPI2_IRQHandler 375 | .thumb_set SPI2_IRQHandler,Default_Handler 376 | 377 | .weak USART1_IRQHandler 378 | .thumb_set USART1_IRQHandler,Default_Handler 379 | 380 | .weak USART2_IRQHandler 381 | .thumb_set USART2_IRQHandler,Default_Handler 382 | 383 | .weak USART3_IRQHandler 384 | .thumb_set USART3_IRQHandler,Default_Handler 385 | 386 | .weak EXTI15_10_IRQHandler 387 | .thumb_set EXTI15_10_IRQHandler,Default_Handler 388 | 389 | .weak RTC_Alarm_IRQHandler 390 | .thumb_set RTC_Alarm_IRQHandler,Default_Handler 391 | 392 | .weak OTG_FS_WKUP_IRQHandler 393 | .thumb_set OTG_FS_WKUP_IRQHandler,Default_Handler 394 | 395 | .weak TIM8_BRK_TIM12_IRQHandler 396 | .thumb_set TIM8_BRK_TIM12_IRQHandler,Default_Handler 397 | 398 | .weak TIM8_UP_TIM13_IRQHandler 399 | .thumb_set TIM8_UP_TIM13_IRQHandler,Default_Handler 400 | 401 | .weak TIM8_TRG_COM_TIM14_IRQHandler 402 | .thumb_set TIM8_TRG_COM_TIM14_IRQHandler,Default_Handler 403 | 404 | .weak TIM8_CC_IRQHandler 405 | .thumb_set TIM8_CC_IRQHandler,Default_Handler 406 | 407 | .weak DMA1_Stream7_IRQHandler 408 | .thumb_set DMA1_Stream7_IRQHandler,Default_Handler 409 | 410 | .weak FSMC_IRQHandler 411 | .thumb_set FSMC_IRQHandler,Default_Handler 412 | 413 | .weak SDIO_IRQHandler 414 | .thumb_set SDIO_IRQHandler,Default_Handler 415 | 416 | .weak TIM5_IRQHandler 417 | .thumb_set TIM5_IRQHandler,Default_Handler 418 | 419 | .weak SPI3_IRQHandler 420 | .thumb_set SPI3_IRQHandler,Default_Handler 421 | 422 | .weak UART4_IRQHandler 423 | .thumb_set UART4_IRQHandler,Default_Handler 424 | 425 | .weak UART5_IRQHandler 426 | .thumb_set UART5_IRQHandler,Default_Handler 427 | 428 | .weak TIM6_DAC_IRQHandler 429 | .thumb_set TIM6_DAC_IRQHandler,Default_Handler 430 | 431 | .weak TIM7_IRQHandler 432 | .thumb_set TIM7_IRQHandler,Default_Handler 433 | 434 | .weak DMA2_Stream0_IRQHandler 435 | .thumb_set DMA2_Stream0_IRQHandler,Default_Handler 436 | 437 | .weak DMA2_Stream1_IRQHandler 438 | .thumb_set DMA2_Stream1_IRQHandler,Default_Handler 439 | 440 | .weak DMA2_Stream2_IRQHandler 441 | .thumb_set DMA2_Stream2_IRQHandler,Default_Handler 442 | 443 | .weak DMA2_Stream3_IRQHandler 444 | .thumb_set DMA2_Stream3_IRQHandler,Default_Handler 445 | 446 | .weak DMA2_Stream4_IRQHandler 447 | .thumb_set DMA2_Stream4_IRQHandler,Default_Handler 448 | 449 | .weak ETH_IRQHandler 450 | .thumb_set ETH_IRQHandler,Default_Handler 451 | 452 | .weak ETH_WKUP_IRQHandler 453 | .thumb_set ETH_WKUP_IRQHandler,Default_Handler 454 | 455 | .weak CAN2_TX_IRQHandler 456 | .thumb_set CAN2_TX_IRQHandler,Default_Handler 457 | 458 | .weak CAN2_RX0_IRQHandler 459 | .thumb_set CAN2_RX0_IRQHandler,Default_Handler 460 | 461 | .weak CAN2_RX1_IRQHandler 462 | .thumb_set CAN2_RX1_IRQHandler,Default_Handler 463 | 464 | .weak CAN2_SCE_IRQHandler 465 | .thumb_set CAN2_SCE_IRQHandler,Default_Handler 466 | 467 | .weak OTG_FS_IRQHandler 468 | .thumb_set OTG_FS_IRQHandler,Default_Handler 469 | 470 | .weak DMA2_Stream5_IRQHandler 471 | .thumb_set DMA2_Stream5_IRQHandler,Default_Handler 472 | 473 | .weak DMA2_Stream6_IRQHandler 474 | .thumb_set DMA2_Stream6_IRQHandler,Default_Handler 475 | 476 | .weak DMA2_Stream7_IRQHandler 477 | .thumb_set DMA2_Stream7_IRQHandler,Default_Handler 478 | 479 | .weak USART6_IRQHandler 480 | .thumb_set USART6_IRQHandler,Default_Handler 481 | 482 | .weak I2C3_EV_IRQHandler 483 | .thumb_set I2C3_EV_IRQHandler,Default_Handler 484 | 485 | .weak I2C3_ER_IRQHandler 486 | .thumb_set I2C3_ER_IRQHandler,Default_Handler 487 | 488 | .weak OTG_HS_EP1_OUT_IRQHandler 489 | .thumb_set OTG_HS_EP1_OUT_IRQHandler,Default_Handler 490 | 491 | .weak OTG_HS_EP1_IN_IRQHandler 492 | .thumb_set OTG_HS_EP1_IN_IRQHandler,Default_Handler 493 | 494 | .weak OTG_HS_WKUP_IRQHandler 495 | .thumb_set OTG_HS_WKUP_IRQHandler,Default_Handler 496 | 497 | .weak OTG_HS_IRQHandler 498 | .thumb_set OTG_HS_IRQHandler,Default_Handler 499 | 500 | .weak DCMI_IRQHandler 501 | .thumb_set DCMI_IRQHandler,Default_Handler 502 | 503 | .weak CRYP_IRQHandler 504 | .thumb_set CRYP_IRQHandler,Default_Handler 505 | 506 | .weak HASH_RNG_IRQHandler 507 | .thumb_set HASH_RNG_IRQHandler,Default_Handler 508 | 509 | .weak FPU_IRQHandler 510 | .thumb_set FPU_IRQHandler,Default_Handler 511 | 512 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 513 | -------------------------------------------------------------------------------- /sys/stm32_flash.ld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neykov/armboot/5324542d5ea1a0720020c6b06e24525a4bd355ac/sys/stm32_flash.ld -------------------------------------------------------------------------------- /sys/system_stm32f4xx.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file system_stm32f4xx.c 4 | * @author MCD Application Team 5 | * @version V1.0.0 6 | * @date 30-September-2011 7 | * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File. 8 | * This file contains the system clock configuration for STM32F4xx devices, 9 | * and is generated by the clock configuration tool 10 | * stm32f4xx_Clock_Configuration_V1.0.0.xls 11 | * 12 | * 1. This file provides two functions and one global variable to be called from 13 | * user application: 14 | * - SystemInit(): Setups the system clock (System clock source, PLL Multiplier 15 | * and Divider factors, AHB/APBx prescalers and Flash settings), 16 | * depending on the configuration made in the clock xls tool. 17 | * This function is called at startup just after reset and 18 | * before branch to main program. This call is made inside 19 | * the "startup_stm32f4xx.s" file. 20 | * 21 | * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used 22 | * by the user application to setup the SysTick 23 | * timer or configure other parameters. 24 | * 25 | * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must 26 | * be called whenever the core clock is changed 27 | * during program execution. 28 | * 29 | * 2. After each device reset the HSI (16 MHz) is used as system clock source. 30 | * Then SystemInit() function is called, in "startup_stm32f4xx.s" file, to 31 | * configure the system clock before to branch to main program. 32 | * 33 | * 3. If the system clock source selected by user fails to startup, the SystemInit() 34 | * function will do nothing and HSI still used as system clock source. User can 35 | * add some code to deal with this issue inside the SetSysClock() function. 36 | * 37 | * 4. The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" define 38 | * in "stm32f4xx.h" file. When HSE is used as system clock source, directly or 39 | * through PLL, and you are using different crystal you have to adapt the HSE 40 | * value to your own configuration. 41 | * 42 | * 5. This file configures the system clock as follows: 43 | *============================================================================= 44 | *============================================================================= 45 | * Supported STM32F4xx device revision | Rev A 46 | *----------------------------------------------------------------------------- 47 | * System Clock source | PLL (HSE) 48 | *----------------------------------------------------------------------------- 49 | * SYSCLK(Hz) | 168000000 50 | *----------------------------------------------------------------------------- 51 | * HCLK(Hz) | 168000000 52 | *----------------------------------------------------------------------------- 53 | * AHB Prescaler | 1 54 | *----------------------------------------------------------------------------- 55 | * APB1 Prescaler | 4 56 | *----------------------------------------------------------------------------- 57 | * APB2 Prescaler | 2 58 | *----------------------------------------------------------------------------- 59 | * HSE Frequency(Hz) | 25000000 60 | *----------------------------------------------------------------------------- 61 | * PLL_M | 25 62 | *----------------------------------------------------------------------------- 63 | * PLL_N | 336 64 | *----------------------------------------------------------------------------- 65 | * PLL_P | 2 66 | *----------------------------------------------------------------------------- 67 | * PLL_Q | 7 68 | *----------------------------------------------------------------------------- 69 | * PLLI2S_N | NA 70 | *----------------------------------------------------------------------------- 71 | * PLLI2S_R | NA 72 | *----------------------------------------------------------------------------- 73 | * I2S input clock | NA 74 | *----------------------------------------------------------------------------- 75 | * VDD(V) | 3.3 76 | *----------------------------------------------------------------------------- 77 | * Main regulator output voltage | Scale1 mode 78 | *----------------------------------------------------------------------------- 79 | * Flash Latency(WS) | 5 80 | *----------------------------------------------------------------------------- 81 | * Prefetch Buffer | OFF 82 | *----------------------------------------------------------------------------- 83 | * Instruction cache | ON 84 | *----------------------------------------------------------------------------- 85 | * Data cache | ON 86 | *----------------------------------------------------------------------------- 87 | * Require 48MHz for USB OTG FS, | Enabled 88 | * SDIO and RNG clock | 89 | *----------------------------------------------------------------------------- 90 | *============================================================================= 91 | ****************************************************************************** 92 | * @attention 93 | * 94 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 95 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 96 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 97 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 98 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 99 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 100 | * 101 | *

© COPYRIGHT 2011 STMicroelectronics

102 | ****************************************************************************** 103 | */ 104 | 105 | /** @addtogroup CMSIS 106 | * @{ 107 | */ 108 | 109 | /** @addtogroup stm32f4xx_system 110 | * @{ 111 | */ 112 | 113 | /** @addtogroup STM32F4xx_System_Private_Includes 114 | * @{ 115 | */ 116 | 117 | #include "stm32f4xx.h" 118 | 119 | /** 120 | * @} 121 | */ 122 | 123 | /** @addtogroup STM32F4xx_System_Private_TypesDefinitions 124 | * @{ 125 | */ 126 | 127 | /** 128 | * @} 129 | */ 130 | 131 | /** @addtogroup STM32F4xx_System_Private_Defines 132 | * @{ 133 | */ 134 | 135 | /************************* Miscellaneous Configuration ************************/ 136 | /*!< Uncomment the following line if you need to use external SRAM mounted 137 | on STM324xG_EVAL board as data memory */ 138 | /* #define DATA_IN_ExtSRAM */ 139 | 140 | /*!< Uncomment the following line if you need to relocate your vector Table in 141 | Internal SRAM. */ 142 | /* #define VECT_TAB_SRAM */ 143 | #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. 144 | This value must be a multiple of 0x200. */ 145 | /******************************************************************************/ 146 | 147 | /************************* PLL Parameters *************************************/ 148 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N */ 149 | #define PLL_M 25 150 | #define PLL_N 336 151 | 152 | /* SYSCLK = PLL_VCO / PLL_P */ 153 | #define PLL_P 2 154 | 155 | /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ */ 156 | #define PLL_Q 7 157 | 158 | /******************************************************************************/ 159 | 160 | /** 161 | * @} 162 | */ 163 | 164 | /** @addtogroup STM32F4xx_System_Private_Macros 165 | * @{ 166 | */ 167 | 168 | /** 169 | * @} 170 | */ 171 | 172 | /** @addtogroup STM32F4xx_System_Private_Variables 173 | * @{ 174 | */ 175 | 176 | uint32_t SystemCoreClock = 168000000; 177 | 178 | __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; 179 | 180 | /** 181 | * @} 182 | */ 183 | 184 | /** @addtogroup STM32F4xx_System_Private_FunctionPrototypes 185 | * @{ 186 | */ 187 | 188 | static void SetSysClock(void); 189 | #ifdef DATA_IN_ExtSRAM 190 | static void SystemInit_ExtMemCtl(void); 191 | #endif /* DATA_IN_ExtSRAM */ 192 | 193 | /** 194 | * @} 195 | */ 196 | 197 | /** @addtogroup STM32F4xx_System_Private_Functions 198 | * @{ 199 | */ 200 | 201 | /** 202 | * @brief Setup the microcontroller system 203 | * Initialize the Embedded Flash Interface, the PLL and update the 204 | * SystemFrequency variable. 205 | * @param None 206 | * @retval None 207 | */ 208 | void SystemInit(void) 209 | { 210 | /* FPU settings ------------------------------------------------------------*/ 211 | #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) 212 | SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ 213 | #endif 214 | 215 | /* Reset the RCC clock configuration to the default reset state ------------*/ 216 | /* Set HSION bit */ 217 | RCC->CR |= (uint32_t)0x00000001; 218 | 219 | /* Reset CFGR register */ 220 | RCC->CFGR = 0x00000000; 221 | 222 | /* Reset HSEON, CSSON and PLLON bits */ 223 | RCC->CR &= (uint32_t)0xFEF6FFFF; 224 | 225 | /* Reset PLLCFGR register */ 226 | RCC->PLLCFGR = 0x24003010; 227 | 228 | /* Reset HSEBYP bit */ 229 | RCC->CR &= (uint32_t)0xFFFBFFFF; 230 | 231 | /* Disable all interrupts */ 232 | RCC->CIR = 0x00000000; 233 | 234 | #ifdef DATA_IN_ExtSRAM 235 | SystemInit_ExtMemCtl(); 236 | #endif /* DATA_IN_ExtSRAM */ 237 | 238 | /* Configure the System clock source, PLL Multiplier and Divider factors, 239 | AHB/APBx prescalers and Flash settings ----------------------------------*/ 240 | SetSysClock(); 241 | 242 | /* Configure the Vector Table location add offset address ------------------*/ 243 | #ifdef VECT_TAB_SRAM 244 | SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ 245 | #else 246 | SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ 247 | #endif 248 | } 249 | 250 | /** 251 | * @brief Update SystemCoreClock variable according to Clock Register Values. 252 | * The SystemCoreClock variable contains the core clock (HCLK), it can 253 | * be used by the user application to setup the SysTick timer or configure 254 | * other parameters. 255 | * 256 | * @note Each time the core clock (HCLK) changes, this function must be called 257 | * to update SystemCoreClock variable value. Otherwise, any configuration 258 | * based on this variable will be incorrect. 259 | * 260 | * @note - The system frequency computed by this function is not the real 261 | * frequency in the chip. It is calculated based on the predefined 262 | * constant and the selected clock source: 263 | * 264 | * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) 265 | * 266 | * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) 267 | * 268 | * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) 269 | * or HSI_VALUE(*) multiplied/divided by the PLL factors. 270 | * 271 | * (*) HSI_VALUE is a constant defined in stm32f4xx.h file (default value 272 | * 16 MHz) but the real value may vary depending on the variations 273 | * in voltage and temperature. 274 | * 275 | * (**) HSE_VALUE is a constant defined in stm32f4xx.h file (default value 276 | * 25 MHz), user has to ensure that HSE_VALUE is same as the real 277 | * frequency of the crystal used. Otherwise, this function may 278 | * have wrong result. 279 | * 280 | * - The result of this function could be not correct when using fractional 281 | * value for HSE crystal. 282 | * 283 | * @param None 284 | * @retval None 285 | */ 286 | void SystemCoreClockUpdate(void) 287 | { 288 | uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2; 289 | 290 | /* Get SYSCLK source -------------------------------------------------------*/ 291 | tmp = RCC->CFGR & RCC_CFGR_SWS; 292 | 293 | switch (tmp) 294 | { 295 | case 0x00: /* HSI used as system clock source */ 296 | SystemCoreClock = HSI_VALUE; 297 | break; 298 | case 0x04: /* HSE used as system clock source */ 299 | SystemCoreClock = HSE_VALUE; 300 | break; 301 | case 0x08: /* PLL used as system clock source */ 302 | 303 | /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N 304 | SYSCLK = PLL_VCO / PLL_P 305 | */ 306 | pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22; 307 | pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; 308 | 309 | if (pllsource != 0) 310 | { 311 | /* HSE used as PLL clock source */ 312 | pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 313 | } 314 | else 315 | { 316 | /* HSI used as PLL clock source */ 317 | pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6); 318 | } 319 | 320 | pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2; 321 | SystemCoreClock = pllvco/pllp; 322 | break; 323 | default: 324 | SystemCoreClock = HSI_VALUE; 325 | break; 326 | } 327 | /* Compute HCLK frequency --------------------------------------------------*/ 328 | /* Get HCLK prescaler */ 329 | tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)]; 330 | /* HCLK frequency */ 331 | SystemCoreClock >>= tmp; 332 | } 333 | 334 | /** 335 | * @brief Configures the System clock source, PLL Multiplier and Divider factors, 336 | * AHB/APBx prescalers and Flash settings 337 | * @Note This function should be called only once the RCC clock configuration 338 | * is reset to the default reset state (done in SystemInit() function). 339 | * @param None 340 | * @retval None 341 | */ 342 | static void SetSysClock(void) 343 | { 344 | /******************************************************************************/ 345 | /* PLL (clocked by HSE) used as System clock source */ 346 | /******************************************************************************/ 347 | __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 348 | 349 | /* Enable HSE */ 350 | RCC->CR |= ((uint32_t)RCC_CR_HSEON); 351 | 352 | /* Wait till HSE is ready and if Time out is reached exit */ 353 | do 354 | { 355 | HSEStatus = RCC->CR & RCC_CR_HSERDY; 356 | StartUpCounter++; 357 | } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); 358 | 359 | if ((RCC->CR & RCC_CR_HSERDY) != RESET) 360 | { 361 | HSEStatus = (uint32_t)0x01; 362 | } 363 | else 364 | { 365 | HSEStatus = (uint32_t)0x00; 366 | } 367 | 368 | if (HSEStatus == (uint32_t)0x01) 369 | { 370 | /* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */ 371 | RCC->APB1ENR |= RCC_APB1ENR_PWREN; 372 | PWR->CR |= PWR_CR_VOS; 373 | 374 | /* HCLK = SYSCLK / 1*/ 375 | RCC->CFGR |= RCC_CFGR_HPRE_DIV1; 376 | 377 | /* PCLK2 = HCLK / 2*/ 378 | RCC->CFGR |= RCC_CFGR_PPRE2_DIV2; 379 | 380 | /* PCLK1 = HCLK / 4*/ 381 | RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; 382 | 383 | /* Configure the main PLL */ 384 | RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | 385 | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24); 386 | 387 | /* Enable the main PLL */ 388 | RCC->CR |= RCC_CR_PLLON; 389 | 390 | /* Wait till the main PLL is ready */ 391 | while((RCC->CR & RCC_CR_PLLRDY) == 0) 392 | { 393 | } 394 | 395 | /* Configure Flash prefetch, Instruction cache, Data cache and wait state */ 396 | FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS; 397 | 398 | /* Select the main PLL as system clock source */ 399 | RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); 400 | RCC->CFGR |= RCC_CFGR_SW_PLL; 401 | 402 | /* Wait till the main PLL is used as system clock source */ 403 | while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL); 404 | { 405 | } 406 | } 407 | else 408 | { /* If HSE fails to start-up, the application will have wrong clock 409 | configuration. User can add here some code to deal with this error */ 410 | } 411 | 412 | } 413 | 414 | /** 415 | * @brief Setup the external memory controller. Called in startup_stm32f4xx.s 416 | * before jump to __main 417 | * @param None 418 | * @retval None 419 | */ 420 | #ifdef DATA_IN_ExtSRAM 421 | /** 422 | * @brief Setup the external memory controller. 423 | * Called in startup_stm32f4xx.s before jump to main. 424 | * This function configures the external SRAM mounted on STM324xG_EVAL board 425 | * This SRAM will be used as program data memory (including heap and stack). 426 | * @param None 427 | * @retval None 428 | */ 429 | void SystemInit_ExtMemCtl(void) 430 | { 431 | /*-- GPIOs Configuration -----------------------------------------------------*/ 432 | /* 433 | +-------------------+--------------------+------------------+------------------+ 434 | + SRAM pins assignment + 435 | +-------------------+--------------------+------------------+------------------+ 436 | | PD0 <-> FSMC_D2 | PE0 <-> FSMC_NBL0 | PF0 <-> FSMC_A0 | PG0 <-> FSMC_A10 | 437 | | PD1 <-> FSMC_D3 | PE1 <-> FSMC_NBL1 | PF1 <-> FSMC_A1 | PG1 <-> FSMC_A11 | 438 | | PD4 <-> FSMC_NOE | PE3 <-> FSMC_A19 | PF2 <-> FSMC_A2 | PG2 <-> FSMC_A12 | 439 | | PD5 <-> FSMC_NWE | PE4 <-> FSMC_A20 | PF3 <-> FSMC_A3 | PG3 <-> FSMC_A13 | 440 | | PD8 <-> FSMC_D13 | PE7 <-> FSMC_D4 | PF4 <-> FSMC_A4 | PG4 <-> FSMC_A14 | 441 | | PD9 <-> FSMC_D14 | PE8 <-> FSMC_D5 | PF5 <-> FSMC_A5 | PG5 <-> FSMC_A15 | 442 | | PD10 <-> FSMC_D15 | PE9 <-> FSMC_D6 | PF12 <-> FSMC_A6 | PG9 <-> FSMC_NE2 | 443 | | PD11 <-> FSMC_A16 | PE10 <-> FSMC_D7 | PF13 <-> FSMC_A7 |------------------+ 444 | | PD12 <-> FSMC_A17 | PE11 <-> FSMC_D8 | PF14 <-> FSMC_A8 | 445 | | PD13 <-> FSMC_A18 | PE12 <-> FSMC_D9 | PF15 <-> FSMC_A9 | 446 | | PD14 <-> FSMC_D0 | PE13 <-> FSMC_D10 |------------------+ 447 | | PD15 <-> FSMC_D1 | PE14 <-> FSMC_D11 | 448 | | | PE15 <-> FSMC_D12 | 449 | +-------------------+--------------------+ 450 | */ 451 | /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */ 452 | RCC->AHB1ENR = 0x00000078; 453 | 454 | /* Connect PDx pins to FSMC Alternate function */ 455 | GPIOD->AFR[0] = 0x00cc00cc; 456 | GPIOD->AFR[1] = 0xcc0ccccc; 457 | /* Configure PDx pins in Alternate function mode */ 458 | GPIOD->MODER = 0xaaaa0a0a; 459 | /* Configure PDx pins speed to 100 MHz */ 460 | GPIOD->OSPEEDR = 0xffff0f0f; 461 | /* Configure PDx pins Output type to push-pull */ 462 | GPIOD->OTYPER = 0x00000000; 463 | /* No pull-up, pull-down for PDx pins */ 464 | GPIOD->PUPDR = 0x00000000; 465 | 466 | /* Connect PEx pins to FSMC Alternate function */ 467 | GPIOE->AFR[0] = 0xc00cc0cc; 468 | GPIOE->AFR[1] = 0xcccccccc; 469 | /* Configure PEx pins in Alternate function mode */ 470 | GPIOE->MODER = 0xaaaa828a; 471 | /* Configure PEx pins speed to 100 MHz */ 472 | GPIOE->OSPEEDR = 0xffffc3cf; 473 | /* Configure PEx pins Output type to push-pull */ 474 | GPIOE->OTYPER = 0x00000000; 475 | /* No pull-up, pull-down for PEx pins */ 476 | GPIOE->PUPDR = 0x00000000; 477 | 478 | /* Connect PFx pins to FSMC Alternate function */ 479 | GPIOF->AFR[0] = 0x00cccccc; 480 | GPIOF->AFR[1] = 0xcccc0000; 481 | /* Configure PFx pins in Alternate function mode */ 482 | GPIOF->MODER = 0xaa000aaa; 483 | /* Configure PFx pins speed to 100 MHz */ 484 | GPIOF->OSPEEDR = 0xff000fff; 485 | /* Configure PFx pins Output type to push-pull */ 486 | GPIOF->OTYPER = 0x00000000; 487 | /* No pull-up, pull-down for PFx pins */ 488 | GPIOF->PUPDR = 0x00000000; 489 | 490 | /* Connect PGx pins to FSMC Alternate function */ 491 | GPIOG->AFR[0] = 0x00cccccc; 492 | GPIOG->AFR[1] = 0x000000c0; 493 | /* Configure PGx pins in Alternate function mode */ 494 | GPIOG->MODER = 0x00080aaa; 495 | /* Configure PGx pins speed to 100 MHz */ 496 | GPIOG->OSPEEDR = 0x000c0fff; 497 | /* Configure PGx pins Output type to push-pull */ 498 | GPIOG->OTYPER = 0x00000000; 499 | /* No pull-up, pull-down for PGx pins */ 500 | GPIOG->PUPDR = 0x00000000; 501 | 502 | /*-- FSMC Configuration ------------------------------------------------------*/ 503 | /* Enable the FSMC interface clock */ 504 | RCC->AHB3ENR = 0x00000001; 505 | 506 | /* Configure and enable Bank1_SRAM2 */ 507 | FSMC_Bank1->BTCR[2] = 0x00001015; 508 | FSMC_Bank1->BTCR[3] = 0x00010603; 509 | FSMC_Bank1E->BWTR[2] = 0x0fffffff; 510 | /* 511 | Bank1_SRAM2 is configured as follow: 512 | 513 | p.FSMC_AddressSetupTime = 3; 514 | p.FSMC_AddressHoldTime = 0; 515 | p.FSMC_DataSetupTime = 6; 516 | p.FSMC_BusTurnAroundDuration = 1; 517 | p.FSMC_CLKDivision = 0; 518 | p.FSMC_DataLatency = 0; 519 | p.FSMC_AccessMode = FSMC_AccessMode_A; 520 | 521 | FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM2; 522 | FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable; 523 | FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_PSRAM; 524 | FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b; 525 | FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable; 526 | FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable; 527 | FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low; 528 | FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable; 529 | FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState; 530 | FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable; 531 | FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable; 532 | FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable; 533 | FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable; 534 | FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p; 535 | FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p; 536 | */ 537 | 538 | } 539 | #endif /* DATA_IN_ExtSRAM */ 540 | 541 | 542 | /** 543 | * @} 544 | */ 545 | 546 | /** 547 | * @} 548 | */ 549 | 550 | /** 551 | * @} 552 | */ 553 | /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/ 554 | -------------------------------------------------------------------------------- /target.json: -------------------------------------------------------------------------------- 1 | { 2 | "data-layout": "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:64:128-a:0:64-n32", 3 | "llvm-target": "thumbv7em-unknown-none-eabihf", 4 | "linker": "arm-none-eabi-gcc", 5 | "target-endian": "little", 6 | "target-pointer-width": "32", 7 | "arch": "arm", 8 | "os": "none", 9 | "cpu": "cortex-m4", 10 | "features": "+thumb2", 11 | "relocation-model": "static", 12 | "linker-is-gnu": true, 13 | "has-rpath": true, 14 | "morestack": false, 15 | "disable-redzone": true, 16 | "executables": true, 17 | "dynamic_linking": false 18 | } 19 | 20 | -------------------------------------------------------------------------------- /zero/std_types.rs: -------------------------------------------------------------------------------- 1 | pub type c_char = i8; 2 | pub type c_schar = i8; 3 | pub type c_uchar = u8; 4 | pub type c_short = i16; 5 | pub type c_ushort = u16; 6 | pub type c_int = i32; 7 | pub type c_uint = u32; 8 | pub type c_long = i32; 9 | pub type c_ulong = u32; 10 | pub type c_float = f32; 11 | pub type c_double = f64; 12 | pub type size_t = u32; 13 | pub type ptrdiff_t = i32; 14 | pub type clock_t = i32; 15 | pub type time_t = i32; 16 | pub type wchar_t = i32; 17 | pub type uint32_t = u32; 18 | 19 | -------------------------------------------------------------------------------- /zero/zero.rs: -------------------------------------------------------------------------------- 1 | #[lang="fail_bounds_check"] 2 | fn fail_bounds_check(_: &(&'static str, uint), 3 | _: uint, _: uint) -> ! { 4 | loop{} 5 | } 6 | 7 | //override system abort to avoid pulling in memory allocation dependencies 8 | #[no_mangle] 9 | pub extern "C" fn __aeabi_unwind_cpp_pr0() { 10 | loop{} 11 | } 12 | 13 | 14 | #[cold] #[inline(never)] 15 | #[lang="panic_bounds_check"] 16 | fn panic_bounds_check(_: &(&'static str, uint), 17 | _: uint, _: uint) -> ! { 18 | loop{} 19 | } 20 | 21 | #[lang="phantom_fn"] 22 | pub trait PhantomFn { } 23 | pub trait MarkerTrait : PhantomFn { } 24 | 25 | #[lang = "sized"] 26 | pub trait Sized : MarkerTrait {} 27 | 28 | #[lang = "copy"] 29 | pub trait Copy : MarkerTrait {} 30 | 31 | #[lang="sync"] 32 | pub trait Sync : MarkerTrait {} 33 | 34 | --------------------------------------------------------------------------------