Nothing Special / mbed-STM32F103C8

Fork of mbed-STM32F103C8_org by Nothing Special

Committer:
mega64
Date:
Thu Mar 16 06:15:53 2017 +0000
Revision:
146:03e976389d16
fully rebuild, now based on mbed-dev v160

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mega64 146:03e976389d16 1 /*
mega64 146:03e976389d16 2 * Copyright (c) 2015-2016, ARM Limited, All Rights Reserved
mega64 146:03e976389d16 3 * SPDX-License-Identifier: Apache-2.0
mega64 146:03e976389d16 4 *
mega64 146:03e976389d16 5 * Licensed under the Apache License, Version 2.0 (the "License"); you may
mega64 146:03e976389d16 6 * not use this file except in compliance with the License.
mega64 146:03e976389d16 7 * You may obtain a copy of the License at
mega64 146:03e976389d16 8 *
mega64 146:03e976389d16 9 * http://www.apache.org/licenses/LICENSE-2.0
mega64 146:03e976389d16 10 *
mega64 146:03e976389d16 11 * Unless required by applicable law or agreed to in writing, software
mega64 146:03e976389d16 12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
mega64 146:03e976389d16 13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mega64 146:03e976389d16 14 * See the License for the specific language governing permissions and
mega64 146:03e976389d16 15 * limitations under the License.
mega64 146:03e976389d16 16 */
mega64 146:03e976389d16 17
mega64 146:03e976389d16 18 /* Declare __STDC_LIMIT_MACROS so stdint.h defines UINT32_MAX when using C++ */
mega64 146:03e976389d16 19 #define __STDC_LIMIT_MACROS
mega64 146:03e976389d16 20 #include "platform/mbed_critical.h"
mega64 146:03e976389d16 21
mega64 146:03e976389d16 22 #include "cmsis.h"
mega64 146:03e976389d16 23 #include "platform/mbed_assert.h"
mega64 146:03e976389d16 24 #include "platform/mbed_toolchain.h"
mega64 146:03e976389d16 25
mega64 146:03e976389d16 26 #define EXCLUSIVE_ACCESS (!defined (__CORTEX_M0) && !defined (__CORTEX_M0PLUS))
mega64 146:03e976389d16 27
mega64 146:03e976389d16 28 static volatile uint32_t interrupt_enable_counter = 0;
mega64 146:03e976389d16 29 static volatile bool critical_interrupts_disabled = false;
mega64 146:03e976389d16 30
mega64 146:03e976389d16 31 bool core_util_are_interrupts_enabled(void)
mega64 146:03e976389d16 32 {
mega64 146:03e976389d16 33 #if defined(__CORTEX_A9)
mega64 146:03e976389d16 34 return ((__get_CPSR() & 0x80) == 0);
mega64 146:03e976389d16 35 #else
mega64 146:03e976389d16 36 return ((__get_PRIMASK() & 0x1) == 0);
mega64 146:03e976389d16 37 #endif
mega64 146:03e976389d16 38 }
mega64 146:03e976389d16 39
mega64 146:03e976389d16 40 MBED_WEAK void core_util_critical_section_enter(void)
mega64 146:03e976389d16 41 {
mega64 146:03e976389d16 42 bool interrupts_disabled = !core_util_are_interrupts_enabled();
mega64 146:03e976389d16 43 __disable_irq();
mega64 146:03e976389d16 44
mega64 146:03e976389d16 45 /* Save the interrupt disabled state as it was prior to any nested critical section lock use */
mega64 146:03e976389d16 46 if (!interrupt_enable_counter) {
mega64 146:03e976389d16 47 critical_interrupts_disabled = interrupts_disabled;
mega64 146:03e976389d16 48 }
mega64 146:03e976389d16 49
mega64 146:03e976389d16 50 /* If the interrupt_enable_counter overflows or we are in a nested critical section and interrupts
mega64 146:03e976389d16 51 are enabled, then something has gone badly wrong thus assert an error.
mega64 146:03e976389d16 52 */
mega64 146:03e976389d16 53 MBED_ASSERT(interrupt_enable_counter < UINT32_MAX);
mega64 146:03e976389d16 54 // FIXME
mega64 146:03e976389d16 55 #ifndef FEATURE_UVISOR
mega64 146:03e976389d16 56 if (interrupt_enable_counter > 0) {
mega64 146:03e976389d16 57 MBED_ASSERT(interrupts_disabled);
mega64 146:03e976389d16 58 }
mega64 146:03e976389d16 59 #else
mega64 146:03e976389d16 60 #warning "core_util_critical_section_enter needs fixing to work from unprivileged code"
mega64 146:03e976389d16 61 #endif /* FEATURE_UVISOR */
mega64 146:03e976389d16 62 interrupt_enable_counter++;
mega64 146:03e976389d16 63 }
mega64 146:03e976389d16 64
mega64 146:03e976389d16 65 MBED_WEAK void core_util_critical_section_exit(void)
mega64 146:03e976389d16 66 {
mega64 146:03e976389d16 67 /* If critical_section_enter has not previously been called, do nothing */
mega64 146:03e976389d16 68 if (interrupt_enable_counter) {
mega64 146:03e976389d16 69
mega64 146:03e976389d16 70 // FIXME
mega64 146:03e976389d16 71 #ifndef FEATURE_UVISOR
mega64 146:03e976389d16 72 bool interrupts_disabled = !core_util_are_interrupts_enabled(); /* get the current interrupt disabled state */
mega64 146:03e976389d16 73
mega64 146:03e976389d16 74 MBED_ASSERT(interrupts_disabled); /* Interrupts must be disabled on invoking an exit from a critical section */
mega64 146:03e976389d16 75 #else
mega64 146:03e976389d16 76 #warning "core_util_critical_section_exit needs fixing to work from unprivileged code"
mega64 146:03e976389d16 77 #endif /* FEATURE_UVISOR */
mega64 146:03e976389d16 78
mega64 146:03e976389d16 79 interrupt_enable_counter--;
mega64 146:03e976389d16 80
mega64 146:03e976389d16 81 /* Only re-enable interrupts if we are exiting the last of the nested critical sections and
mega64 146:03e976389d16 82 interrupts were enabled on entry to the first critical section.
mega64 146:03e976389d16 83 */
mega64 146:03e976389d16 84 if (!interrupt_enable_counter && !critical_interrupts_disabled) {
mega64 146:03e976389d16 85 __enable_irq();
mega64 146:03e976389d16 86 }
mega64 146:03e976389d16 87 }
mega64 146:03e976389d16 88 }
mega64 146:03e976389d16 89
mega64 146:03e976389d16 90 #if EXCLUSIVE_ACCESS
mega64 146:03e976389d16 91
mega64 146:03e976389d16 92 /* Supress __ldrex and __strex deprecated warnings - "#3731-D: intrinsic is deprecated" */
mega64 146:03e976389d16 93 #if defined (__CC_ARM)
mega64 146:03e976389d16 94 #pragma diag_suppress 3731
mega64 146:03e976389d16 95 #endif
mega64 146:03e976389d16 96
mega64 146:03e976389d16 97 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
mega64 146:03e976389d16 98 {
mega64 146:03e976389d16 99 uint8_t currentValue = __LDREXB((volatile uint8_t*)ptr);
mega64 146:03e976389d16 100 if (currentValue != *expectedCurrentValue) {
mega64 146:03e976389d16 101 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 102 __CLREX();
mega64 146:03e976389d16 103 return false;
mega64 146:03e976389d16 104 }
mega64 146:03e976389d16 105
mega64 146:03e976389d16 106 return !__STREXB(desiredValue, (volatile uint8_t*)ptr);
mega64 146:03e976389d16 107 }
mega64 146:03e976389d16 108
mega64 146:03e976389d16 109 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
mega64 146:03e976389d16 110 {
mega64 146:03e976389d16 111 uint16_t currentValue = __LDREXH((volatile uint16_t*)ptr);
mega64 146:03e976389d16 112 if (currentValue != *expectedCurrentValue) {
mega64 146:03e976389d16 113 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 114 __CLREX();
mega64 146:03e976389d16 115 return false;
mega64 146:03e976389d16 116 }
mega64 146:03e976389d16 117
mega64 146:03e976389d16 118 return !__STREXH(desiredValue, (volatile uint16_t*)ptr);
mega64 146:03e976389d16 119 }
mega64 146:03e976389d16 120
mega64 146:03e976389d16 121
mega64 146:03e976389d16 122 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
mega64 146:03e976389d16 123 {
mega64 146:03e976389d16 124 uint32_t currentValue = __LDREXW((volatile uint32_t*)ptr);
mega64 146:03e976389d16 125 if (currentValue != *expectedCurrentValue) {
mega64 146:03e976389d16 126 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 127 __CLREX();
mega64 146:03e976389d16 128 return false;
mega64 146:03e976389d16 129 }
mega64 146:03e976389d16 130
mega64 146:03e976389d16 131 return !__STREXW(desiredValue, (volatile uint32_t*)ptr);
mega64 146:03e976389d16 132 }
mega64 146:03e976389d16 133
mega64 146:03e976389d16 134 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
mega64 146:03e976389d16 135 {
mega64 146:03e976389d16 136 uint8_t newValue;
mega64 146:03e976389d16 137 do {
mega64 146:03e976389d16 138 newValue = __LDREXB((volatile uint8_t*)valuePtr) + delta;
mega64 146:03e976389d16 139 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
mega64 146:03e976389d16 140 return newValue;
mega64 146:03e976389d16 141 }
mega64 146:03e976389d16 142
mega64 146:03e976389d16 143 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
mega64 146:03e976389d16 144 {
mega64 146:03e976389d16 145 uint16_t newValue;
mega64 146:03e976389d16 146 do {
mega64 146:03e976389d16 147 newValue = __LDREXH((volatile uint16_t*)valuePtr) + delta;
mega64 146:03e976389d16 148 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
mega64 146:03e976389d16 149 return newValue;
mega64 146:03e976389d16 150 }
mega64 146:03e976389d16 151
mega64 146:03e976389d16 152 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
mega64 146:03e976389d16 153 {
mega64 146:03e976389d16 154 uint32_t newValue;
mega64 146:03e976389d16 155 do {
mega64 146:03e976389d16 156 newValue = __LDREXW((volatile uint32_t*)valuePtr) + delta;
mega64 146:03e976389d16 157 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
mega64 146:03e976389d16 158 return newValue;
mega64 146:03e976389d16 159 }
mega64 146:03e976389d16 160
mega64 146:03e976389d16 161
mega64 146:03e976389d16 162 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
mega64 146:03e976389d16 163 {
mega64 146:03e976389d16 164 uint8_t newValue;
mega64 146:03e976389d16 165 do {
mega64 146:03e976389d16 166 newValue = __LDREXB((volatile uint8_t*)valuePtr) - delta;
mega64 146:03e976389d16 167 } while (__STREXB(newValue, (volatile uint8_t*)valuePtr));
mega64 146:03e976389d16 168 return newValue;
mega64 146:03e976389d16 169 }
mega64 146:03e976389d16 170
mega64 146:03e976389d16 171 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
mega64 146:03e976389d16 172 {
mega64 146:03e976389d16 173 uint16_t newValue;
mega64 146:03e976389d16 174 do {
mega64 146:03e976389d16 175 newValue = __LDREXH((volatile uint16_t*)valuePtr) - delta;
mega64 146:03e976389d16 176 } while (__STREXH(newValue, (volatile uint16_t*)valuePtr));
mega64 146:03e976389d16 177 return newValue;
mega64 146:03e976389d16 178 }
mega64 146:03e976389d16 179
mega64 146:03e976389d16 180 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
mega64 146:03e976389d16 181 {
mega64 146:03e976389d16 182 uint32_t newValue;
mega64 146:03e976389d16 183 do {
mega64 146:03e976389d16 184 newValue = __LDREXW((volatile uint32_t*)valuePtr) - delta;
mega64 146:03e976389d16 185 } while (__STREXW(newValue, (volatile uint32_t*)valuePtr));
mega64 146:03e976389d16 186 return newValue;
mega64 146:03e976389d16 187 }
mega64 146:03e976389d16 188
mega64 146:03e976389d16 189 #else
mega64 146:03e976389d16 190
mega64 146:03e976389d16 191 bool core_util_atomic_cas_u8(uint8_t *ptr, uint8_t *expectedCurrentValue, uint8_t desiredValue)
mega64 146:03e976389d16 192 {
mega64 146:03e976389d16 193 bool success;
mega64 146:03e976389d16 194 uint8_t currentValue;
mega64 146:03e976389d16 195 core_util_critical_section_enter();
mega64 146:03e976389d16 196 currentValue = *ptr;
mega64 146:03e976389d16 197 if (currentValue == *expectedCurrentValue) {
mega64 146:03e976389d16 198 *ptr = desiredValue;
mega64 146:03e976389d16 199 success = true;
mega64 146:03e976389d16 200 } else {
mega64 146:03e976389d16 201 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 202 success = false;
mega64 146:03e976389d16 203 }
mega64 146:03e976389d16 204 core_util_critical_section_exit();
mega64 146:03e976389d16 205 return success;
mega64 146:03e976389d16 206 }
mega64 146:03e976389d16 207
mega64 146:03e976389d16 208 bool core_util_atomic_cas_u16(uint16_t *ptr, uint16_t *expectedCurrentValue, uint16_t desiredValue)
mega64 146:03e976389d16 209 {
mega64 146:03e976389d16 210 bool success;
mega64 146:03e976389d16 211 uint16_t currentValue;
mega64 146:03e976389d16 212 core_util_critical_section_enter();
mega64 146:03e976389d16 213 currentValue = *ptr;
mega64 146:03e976389d16 214 if (currentValue == *expectedCurrentValue) {
mega64 146:03e976389d16 215 *ptr = desiredValue;
mega64 146:03e976389d16 216 success = true;
mega64 146:03e976389d16 217 } else {
mega64 146:03e976389d16 218 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 219 success = false;
mega64 146:03e976389d16 220 }
mega64 146:03e976389d16 221 core_util_critical_section_exit();
mega64 146:03e976389d16 222 return success;
mega64 146:03e976389d16 223 }
mega64 146:03e976389d16 224
mega64 146:03e976389d16 225
mega64 146:03e976389d16 226 bool core_util_atomic_cas_u32(uint32_t *ptr, uint32_t *expectedCurrentValue, uint32_t desiredValue)
mega64 146:03e976389d16 227 {
mega64 146:03e976389d16 228 bool success;
mega64 146:03e976389d16 229 uint32_t currentValue;
mega64 146:03e976389d16 230 core_util_critical_section_enter();
mega64 146:03e976389d16 231 currentValue = *ptr;
mega64 146:03e976389d16 232 if (currentValue == *expectedCurrentValue) {
mega64 146:03e976389d16 233 *ptr = desiredValue;
mega64 146:03e976389d16 234 success = true;
mega64 146:03e976389d16 235 } else {
mega64 146:03e976389d16 236 *expectedCurrentValue = currentValue;
mega64 146:03e976389d16 237 success = false;
mega64 146:03e976389d16 238 }
mega64 146:03e976389d16 239 core_util_critical_section_exit();
mega64 146:03e976389d16 240 return success;
mega64 146:03e976389d16 241 }
mega64 146:03e976389d16 242
mega64 146:03e976389d16 243
mega64 146:03e976389d16 244 uint8_t core_util_atomic_incr_u8(uint8_t *valuePtr, uint8_t delta)
mega64 146:03e976389d16 245 {
mega64 146:03e976389d16 246 uint8_t newValue;
mega64 146:03e976389d16 247 core_util_critical_section_enter();
mega64 146:03e976389d16 248 newValue = *valuePtr + delta;
mega64 146:03e976389d16 249 *valuePtr = newValue;
mega64 146:03e976389d16 250 core_util_critical_section_exit();
mega64 146:03e976389d16 251 return newValue;
mega64 146:03e976389d16 252 }
mega64 146:03e976389d16 253
mega64 146:03e976389d16 254 uint16_t core_util_atomic_incr_u16(uint16_t *valuePtr, uint16_t delta)
mega64 146:03e976389d16 255 {
mega64 146:03e976389d16 256 uint16_t newValue;
mega64 146:03e976389d16 257 core_util_critical_section_enter();
mega64 146:03e976389d16 258 newValue = *valuePtr + delta;
mega64 146:03e976389d16 259 *valuePtr = newValue;
mega64 146:03e976389d16 260 core_util_critical_section_exit();
mega64 146:03e976389d16 261 return newValue;
mega64 146:03e976389d16 262 }
mega64 146:03e976389d16 263
mega64 146:03e976389d16 264 uint32_t core_util_atomic_incr_u32(uint32_t *valuePtr, uint32_t delta)
mega64 146:03e976389d16 265 {
mega64 146:03e976389d16 266 uint32_t newValue;
mega64 146:03e976389d16 267 core_util_critical_section_enter();
mega64 146:03e976389d16 268 newValue = *valuePtr + delta;
mega64 146:03e976389d16 269 *valuePtr = newValue;
mega64 146:03e976389d16 270 core_util_critical_section_exit();
mega64 146:03e976389d16 271 return newValue;
mega64 146:03e976389d16 272 }
mega64 146:03e976389d16 273
mega64 146:03e976389d16 274
mega64 146:03e976389d16 275 uint8_t core_util_atomic_decr_u8(uint8_t *valuePtr, uint8_t delta)
mega64 146:03e976389d16 276 {
mega64 146:03e976389d16 277 uint8_t newValue;
mega64 146:03e976389d16 278 core_util_critical_section_enter();
mega64 146:03e976389d16 279 newValue = *valuePtr - delta;
mega64 146:03e976389d16 280 *valuePtr = newValue;
mega64 146:03e976389d16 281 core_util_critical_section_exit();
mega64 146:03e976389d16 282 return newValue;
mega64 146:03e976389d16 283 }
mega64 146:03e976389d16 284
mega64 146:03e976389d16 285 uint16_t core_util_atomic_decr_u16(uint16_t *valuePtr, uint16_t delta)
mega64 146:03e976389d16 286 {
mega64 146:03e976389d16 287 uint16_t newValue;
mega64 146:03e976389d16 288 core_util_critical_section_enter();
mega64 146:03e976389d16 289 newValue = *valuePtr - delta;
mega64 146:03e976389d16 290 *valuePtr = newValue;
mega64 146:03e976389d16 291 core_util_critical_section_exit();
mega64 146:03e976389d16 292 return newValue;
mega64 146:03e976389d16 293 }
mega64 146:03e976389d16 294
mega64 146:03e976389d16 295 uint32_t core_util_atomic_decr_u32(uint32_t *valuePtr, uint32_t delta)
mega64 146:03e976389d16 296 {
mega64 146:03e976389d16 297 uint32_t newValue;
mega64 146:03e976389d16 298 core_util_critical_section_enter();
mega64 146:03e976389d16 299 newValue = *valuePtr - delta;
mega64 146:03e976389d16 300 *valuePtr = newValue;
mega64 146:03e976389d16 301 core_util_critical_section_exit();
mega64 146:03e976389d16 302 return newValue;
mega64 146:03e976389d16 303 }
mega64 146:03e976389d16 304
mega64 146:03e976389d16 305 #endif
mega64 146:03e976389d16 306
mega64 146:03e976389d16 307
mega64 146:03e976389d16 308 bool core_util_atomic_cas_ptr(void **ptr, void **expectedCurrentValue, void *desiredValue) {
mega64 146:03e976389d16 309 return core_util_atomic_cas_u32(
mega64 146:03e976389d16 310 (uint32_t *)ptr,
mega64 146:03e976389d16 311 (uint32_t *)expectedCurrentValue,
mega64 146:03e976389d16 312 (uint32_t)desiredValue);
mega64 146:03e976389d16 313 }
mega64 146:03e976389d16 314
mega64 146:03e976389d16 315 void *core_util_atomic_incr_ptr(void **valuePtr, ptrdiff_t delta) {
mega64 146:03e976389d16 316 return (void *)core_util_atomic_incr_u32((uint32_t *)valuePtr, (uint32_t)delta);
mega64 146:03e976389d16 317 }
mega64 146:03e976389d16 318
mega64 146:03e976389d16 319 void *core_util_atomic_decr_ptr(void **valuePtr, ptrdiff_t delta) {
mega64 146:03e976389d16 320 return (void *)core_util_atomic_decr_u32((uint32_t *)valuePtr, (uint32_t)delta);
mega64 146:03e976389d16 321 }
mega64 146:03e976389d16 322