Blame view

RIOT/cpu/cortexm_common/include/cpu.h 3.02 KB
a752c7ab   elopes   add first test an...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
  /*
   * Copyright (C) 2014-2015 Freie Universität Berlin
   *
   * This file is subject to the terms and conditions of the GNU Lesser
   * General Public License v2.1. See the file LICENSE in the top level
   * directory for more details.
   */
  
  /**
   * @defgroup    cpu_cortexm_common ARM Cortex-M common
   * @ingroup     cpu
   * @brief       Common implementations and headers for Cortex-M family based
   *              micro-controllers
   * @{
   *
   * @file
   * @brief       Basic definitions for the Cortex-M common module
   *
   * When ever you want to do something hardware related, that is accessing MCUs
   * registers, just include this file. It will then make sure that the MCU
   * specific headers are included.
   *
   * @author      Stefan Pfeiffer <stefan.pfeiffer@fu-berlin.de>
   * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
   * @author      Joakim Nohlgård <joakim.nohlgard@eistec.se>
   *
   * @todo        remove include irq.h once core was adjusted
   */
  
  #ifndef CPU_H
  #define CPU_H
  
  #include <stdio.h>
  
  #include "irq.h"
  #include "sched.h"
  #include "thread.h"
  #include "cpu_conf.h"
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /**
   * @brief Interrupt stack canary value
   *
   * @note 0xe7fe is the ARM Thumb machine code equivalent of asm("bl #-2\n") or
   * 'while (1);', i.e. an infinite loop.
   * @internal
   */
  #define STACK_CANARY_WORD   (0xE7FEE7FEu)
  
  /**
   * @brief   All Cortex-m-based CPUs provide pm_set_lowest
   *
   * The pm_set_lowest is provided either by the pm_layered module if used, or
   * alternatively as fallback by the cortexm's own implementation.
   */
  #define PROVIDES_PM_SET_LOWEST
  
  /**
   * @brief   Initialization of the CPU
   */
  void cpu_init(void);
  
  /**
   * @brief   Initialize Cortex-M specific core parts of the CPU
   */
  void cortexm_init(void);
  
  /**
   * @brief   Prints the current content of the link register (lr)
   */
  static inline void cpu_print_last_instruction(void)
  {
      uint32_t *lr_ptr;
      __asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr));
      printf("%p\n", (void*) lr_ptr);
  }
  
  /**
   * @brief   Put the CPU into the 'wait for event' sleep mode
   *
   * This function is meant to be used for short periods of time, where it is not
   * feasible to switch to the idle thread and back.
   */
  static inline void cortexm_sleep_until_event(void)
  {
      __WFE();
  }
  
  /**
   * @brief   Put the CPU into (deep) sleep mode, using the `WFI` instruction
   *
   * @param[in] deep      !=0 for deep sleep, 0 for light sleep
   */
  static inline void cortexm_sleep(int deep)
  {
      if (deep) {
          SCB->SCR |=  (SCB_SCR_SLEEPDEEP_Msk);
      }
      else {
          SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk);
      }
  
      /* ensure that all memory accesses have completed and trigger sleeping */
      unsigned state = irq_disable();
      __DSB();
      __WFI();
      irq_restore(state);
  }
  
  /**
   * @brief   Trigger a conditional context scheduler run / context switch
   *
   * This function is supposed to be called in the end of each ISR.
   */
  static inline void cortexm_isr_end(void)
  {
      if (sched_context_switch_request) {
          thread_yield();
      }
  }
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif /* CPU_H */
  /** @} */