Biomimetics MBED Library w/ Added Support for CAN3

Dependents:   CAN_TEST SPIne_Plus_DYNO_SENSORS SPIne_Plus_v2 SPIne_Plus_Dyno_v2

Committer:
saloutos
Date:
Thu Nov 26 04:08:56 2020 +0000
Revision:
0:083111ae2a11
first commit of leaned mbed dev lib

Who changed what in which revision?

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