BSPACM  20150113
Board Support Package for ARM Cortex-M Microcontrollers
core.h
Go to the documentation of this file.
1 /* Copyright 2014, Peter A. Bigot
2  *
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * * Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * * Neither the name of the software nor the names of its contributors may be
16  * used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
40 #ifndef BSPACM_CORE_H
41 #define BSPACM_CORE_H
42 
43 #if (__cplusplus - 0)
44 #include <cstdint>
45 #include <cstddef>
46 #else /* __cplusplus */
47 #include <stdint.h>
48 #include <stddef.h>
49 #include <stdbool.h>
50 #endif /* __cplusplus */
51 
64 #if defined(BSPACM_DOXYGEN) || (BSPACM_CORE_TOOLCHAIN_GCC - 0)
65 #define BSPACM_CORE_INLINE __inline__
66 #else /* TOOLCHAIN */
67 #define BSPACM_CORE_INLINE inline
68 #endif /* TOOLCHAIN */
69 
76 #if defined(BSPACM_DOXYGEN) || (BSPACM_CORE_TOOLCHAIN_GCC - 0)
77 /* GCC wants both directives */
78 #define BSPACM_CORE_INLINE_FORCED BSPACM_CORE_INLINE __attribute__((__always_inline__))
79 #else /* TOOLCHAIN */
80 #define BSPACM_CORE_INLINE_FORCED BSPACM_CORE_INLINE
81 #endif /* TOOLCHAIN */
82 
91 #if defined(BSPACM_DOXYGEN) || (BSPACM_CORE_TOOLCHAIN_GCC - 0)
92 #define BSPACM_CORE_PACKED_STRUCT(nm_) struct __attribute__((__packed__)) nm_
93 #endif /* TOOLCHAIN */
94 
104 #if defined(BSPACM_DOXYGEN) || (BSPACM_CORE_TOOLCHAIN_GCC - 0)
105 #define BSPACM_CORE_ALIGNED_OBJECT(sz_) __attribute__((__aligned__(sz_)))
106 #endif /* TOOLCHAIN */
107 
108 /* Device-specific material. This includes device vendor and CMSIS
109  * headers, and provides any necessary bridging declarations. The
110  * correct content should be located by the prioritization of include
111  * paths, but is generally found in the device/SERIES include
112  * hierarchy. */
113 #include <bspacm/device.h>
114 
115 /* Application/board-specific material. This corresponds to the
116  * material in @c periph_config.c, and has things such as the handle
117  * to the default system UART peripheral. A default is provided in
118  * each board-specific include hierarchy, but it can be overridden by
119  * providing a path to another file in the providing a higher-priority
120  * path in the application-specific Makefile. */
121 #include <bspacm/config.h>
122 
128 #define BSPACM_VERSION 20150113
129 
132 #define BSPACM_CORE_DISABLE_INTERRUPT() __disable_irq()
133 
136 #define BSPACM_CORE_ENABLE_INTERRUPT() __enable_irq()
137 
148 #define BSPACM_CORE_SAVED_INTERRUPT_STATE(var_) unsigned int const var_ = __get_PRIMASK()
149 
154 #define BSPACM_CORE_RESTORE_INTERRUPT_STATE(var_) do { \
155  if (1U & var_) { \
156  BSPACM_CORE_DISABLE_INTERRUPT(); \
157  } else { \
158  BSPACM_CORE_ENABLE_INTERRUPT(); \
159  } \
160  } while (0)
161 
165 #define BSPACM_CORE_REENABLE_INTERRUPT(var_) do { \
166  if (! (1U & var_)) { \
167  BSPACM_CORE_ENABLE_INTERRUPT(); \
168  } \
169  } while (0)
170 
171 #if defined(BSPACM_DOXYGEN) || (! defined(BSPACM_CORE_SLEEP))
172 
192 #define BSPACM_CORE_SLEEP() do { \
193  __WFI(); \
194  } while(0)
195 #endif /* BSPACM_CORE_SLEEP */
196 
197 #if defined(BSPACM_DOXYGEN) || (! defined(BSPACM_CORE_DEEP_SLEEP))
198 
226 #define BSPACM_CORE_DEEP_SLEEP() do { \
227  uint32_t in_sleepdeep = (SCB->SCR & SCB_SCR_SLEEPDEEP_Msk); \
228  SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; \
229  __WFI(); \
230  SCB->SCR &= ~in_sleepdeep; \
231  } while(0)
232 #endif /* BSPACM_CORE_DEEP_SLEEP */
233 
236 #if defined(DWT_CTRL_NOCYCCNT_Msk)
237 #define BSPACM_CORE_SUPPORTS_CYCCNT 1
238 #else /* DWT_CTRL_NOCYCCNT_Msk */
239 #define BSPACM_CORE_SUPPORTS_CYCCNT 0
240 #endif /* DWT_CTRL_NOCYCCNT_Msk */
241 
249 #if (BSPACM_CORE_SUPPORTS_CYCCNT - 0)
250 #define BSPACM_CORE_ENABLE_CYCCNT() do { \
251  if (! (DWT_CTRL_NOCYCCNT_Msk & DWT->CTRL)) { \
252  CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; \
253  DWT->CYCCNT = 0; \
254  DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; \
255  } \
256  } while (0)
257 #else /* BSPACM_CORE_SUPPORTS_CYCCNT */
258 #define BSPACM_CORE_ENABLE_CYCCNT() do { } while (0)
259 #endif /* BSPACM_CORE_SUPPORTS_CYCCNT */
260 
263 #if (BSPACM_CORE_SUPPORTS_CYCCNT - 0)
264 #define BSPACM_CORE_DISABLE_CYCCNT() do { \
265  if (! (DWT_CTRL_NOCYCCNT_Msk & DWT->CTRL)) { \
266  DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk; \
267  CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk; \
268  } \
269  } while (0)
270 #else /* BSPACM_CORE_SUPPORTS_CYCCNT */
271 #define BSPACM_CORE_DISABLE_CYCCNT() do { } while (0)
272 #endif /* BSPACM_CORE_SUPPORTS_CYCCNT */
273 
282 #if (BSPACM_CORE_SUPPORTS_CYCCNT - 0)
283 #define BSPACM_CORE_CYCCNT() DWT->CYCCNT
284 #else /* BSPACM_CORE_SUPPORTS_CYCCNT */
285 #define BSPACM_CORE_CYCCNT() 0
286 #endif /* BSPACM_CORE_SUPPORTS_CYCCNT */
287 
294 #if (BSPACM_CORE_SUPPORTS_CYCCNT - 0)
295 #define BSPACM_CORE_DELAY_CYCLES(cycles_) do { \
296  uint32_t const delta = (cycles_); \
297  uint32_t const cc0 = DWT->CYCCNT; \
298  while ((DWT->CYCCNT - cc0) < delta) { \
299  /* spin */ \
300  } \
301  } while (0)
302 #else /* BSPACM_CORE_SUPPORTS_CYCCNT */
303 #define BSPACM_CORE_DELAY_CYCLES(cycles_) do { \
304  uint32_t const cycles_per_iter = 3; \
305  uint32_t remaining = (cycles_); \
306  while (remaining > cycles_per_iter) { \
307  remaining -= cycles_per_iter; \
308  } \
309  } while (0)
310 #endif /* BSPACM_CORE_SUPPORTS_CYCCNT */
311 
312 /* Cortex-M3 devices support bit-band access to SRAM and peripherals,
313  * but Cortex-M0+ does not, so the following features are optional. */
314 
315 #if defined(BSPACM_DOXYGEN) || (defined(BSPACM_CORE_SRAM_BASE) && defined(BSPACM_CORE_SRAM_BITBAND_BASE))
316 /* @cond DOXYGEN_EXCLUDE */
317 #define BSPACM_CORE_BITBAND_SRAM_(object_, bit_) (BSPACM_CORE_SRAM_BITBAND_BASE + 4 * ((bit_) + 8 * ((uintptr_t)&(object_) - BSPACM_CORE_SRAM_BASE)))
318 /* @endcond */
319 
339 #define BSPACM_CORE_BITBAND_SRAM32(object_, bit_) (*(volatile uint32_t *)BSPACM_CORE_BITBAND_SRAM_(object_, bit_))
340 
344 #define BSPACM_CORE_BITBAND_SRAM16(object_, bit_) (*(volatile uint16_t *)BSPACM_CORE_BITBAND_SRAM_(object_, bit_))
345 
349 #define BSPACM_CORE_BITBAND_SRAM8(object_, bit_) (*(volatile uint8_t *)BSPACM_CORE_BITBAND_SRAM_(object_, bit_))
350 
351 #endif /* SRAM bitband supported */
352 
353 #if defined(BSPACM_DOXYGEN) || (defined(BSPACM_CORE_PERIPH_BASE) && defined(BSPACM_CORE_PERIPH_BITBAND_BASE))
354 
374 #define BSPACM_CORE_BITBAND_PERIPH(object_, bit_) (*(volatile uint32_t *)(BSPACM_CORE_PERIPH_BITBAND_BASE + 4 * ((bit_) + 8 * ((uintptr_t)&(object_) - BSPACM_CORE_PERIPH_BASE))))
375 #endif /* PERIPH bitband supported */
376 
391 static BSPACM_CORE_INLINE
392 unsigned int
393 uiBSPACMcoreBitFromMask (uint32_t mask)
394 {
395  if (0x1U == mask) {
396  return 0;
397  } else if (0x2U == mask) {
398  return 1;
399  } else if (0x4U == mask) {
400  return 2;
401  } else if (0x8U == mask) {
402  return 3;
403  } else if (0x10U == mask) {
404  return 4;
405  } else if (0x20U == mask) {
406  return 5;
407  } else if (0x40U == mask) {
408  return 6;
409  } else if (0x80U == mask) {
410  return 7;
411  } else if (0x100U == mask) {
412  return 8;
413  } else if (0x200U == mask) {
414  return 9;
415  } else if (0x400U == mask) {
416  return 10;
417  } else if (0x800U == mask) {
418  return 11;
419  } else if (0x1000U == mask) {
420  return 12;
421  } else if (0x2000U == mask) {
422  return 13;
423  } else if (0x4000U == mask) {
424  return 14;
425  } else if (0x8000U == mask) {
426  return 15;
427  } else if (0x10000U == mask) {
428  return 16;
429  } else if (0x20000U == mask) {
430  return 17;
431  } else if (0x40000U == mask) {
432  return 18;
433  } else if (0x80000U == mask) {
434  return 19;
435  } else if (0x100000U == mask) {
436  return 20;
437  } else if (0x200000U == mask) {
438  return 21;
439  } else if (0x400000U == mask) {
440  return 22;
441  } else if (0x800000U == mask) {
442  return 23;
443  } else if (0x1000000U == mask) {
444  return 24;
445  } else if (0x2000000U == mask) {
446  return 25;
447  } else if (0x4000000U == mask) {
448  return 26;
449  } else if (0x8000000U == mask) {
450  return 27;
451  } else if (0x10000000U == mask) {
452  return 28;
453  } else if (0x20000000U == mask) {
454  return 29;
455  } else if (0x40000000U == mask) {
456  return 30;
457  } else if (0x80000000U != mask) {
458  /* Not exactly one bit set. This is an error in usage. */
459  while(1);
460  }
461  return 31;
462 }
463 
478 static BSPACM_CORE_INLINE
479 void vBSPACMcoreSetPinNybble (volatile uint32_t * basep,
480  unsigned int pin,
481  unsigned int value)
482 {
483  volatile uint32_t * const wordp = basep + (pin / 8);
484  const unsigned int shift = 4 * (pin % 8);
485  *wordp = (*wordp & ~(0x0F << shift)) | ((0x0F & value) << shift);
486 }
487 
488 #endif /* BSPACM_CORE_H */
Application/board-specific header.
static BSPACM_CORE_INLINE void vBSPACMcoreSetPinNybble(volatile uint32_t *basep, unsigned int pin, unsigned int value)
Definition: core.h:479
#define BSPACM_CORE_INLINE
Definition: core.h:65
static BSPACM_CORE_INLINE unsigned int uiBSPACMcoreBitFromMask(uint32_t mask)
Definition: core.h:393