Blame view

RIOT/cpu/nrf5x_common/periph/rtt.c 2.78 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
131
132
133
134
135
136
137
138
  /*
   * Copyright (C) 2014-2017 Freie Universitรคt Berlin
   *               2015 Jan Wagner <mail@jwagner.eu>
   *
   * 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.
   */
  
  /**
   * @ingroup     cpu_nrf5x_common
   * @ingroup     drivers_periph_rtt
   * @{
   *
   * @file
   * @brief       RTT implementation for NRF5x CPUs
   *
   * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
   * @author      Jan Wagner <mail@jwagner.eu>
   *
   * @}
   */
  
  #include "cpu.h"
  #include "nrf_clock.h"
  #include "periph/rtt.h"
  
  /* get the IRQ configuration */
  #if (RTT_DEV == 1)
  #define DEV             NRF_RTC1
  #define ISR             isr_rtc1
  #define IRQn            RTC1_IRQn
  #elif (RTT_DEV == 2)
  #define DEV             NRF_RTC2
  #define ISR             isr_rtc2
  #define IRQn            RTC2_IRQn
  #else
  #error "RTT configuration: invalid or no RTC device specified (RTT_DEV)"
  #endif
  
  #define LFCLK_FREQ      (32768U)
  
  /* allocate memory for callbacks and their args */
  static rtt_cb_t alarm_cb;
  static void *alarm_arg;
  static rtt_cb_t overflow_cb;
  static void *overflow_arg;
  
  void rtt_init(void)
  {
      /* enable the low-frequency clock */
      clock_start_lf();
      /* make sure device is powered */
  #ifdef CPU_FAM_NRF51
      DEV->POWER = 1;
  #endif
      /* stop the RTT during configuration */
      DEV->TASKS_STOP = 1;
      /* configure interrupt */
      NVIC_EnableIRQ(IRQn);
      /* set prescaler */
      DEV->PRESCALER = (LFCLK_FREQ / RTT_FREQUENCY) - 1;
      /* start the actual RTT thing */
      DEV->TASKS_START = 1;
  }
  
  void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
  {
      overflow_cb = cb;
      overflow_arg = arg;
      DEV->INTENSET = RTC_INTENSET_OVRFLW_Msk;
  }
  
  void rtt_clear_overflow_cb(void)
  {
      DEV->INTENCLR = RTC_INTENCLR_OVRFLW_Msk;
  }
  
  uint32_t rtt_get_counter(void)
  {
      return DEV->COUNTER;
  }
  
  void rtt_set_counter(uint32_t counter)
  {
      (void) counter;
      /* not supported by the nRF5x */
  }
  
  void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
  {
      alarm_cb = cb;
      alarm_arg = arg;
      DEV->CC[0] = (alarm & RTT_MAX_VALUE);
      DEV->INTENSET = RTC_INTENSET_COMPARE0_Msk;
  }
  
  uint32_t rtt_get_alarm(void)
  {
      return DEV->CC[0];
  }
  
  void rtt_clear_alarm(void)
  {
      DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
  }
  
  void rtt_poweron(void)
  {
  #ifdef CPU_FAM_NRF51
      DEV->POWER = 1;
  #endif
      DEV->TASKS_START = 1;
  }
  
  void rtt_poweroff(void)
  {
      DEV->TASKS_STOP = 1;
  #ifdef CPU_FAM_NRF51
      DEV->POWER = 0;
  #endif
  }
  
  void ISR(void)
  {
      if (DEV->EVENTS_COMPARE[0] == 1) {
          DEV->EVENTS_COMPARE[0] = 0;
          DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
          alarm_cb(alarm_arg);
      }
  
      if (DEV->EVENTS_OVRFLW == 1) {
          DEV->EVENTS_OVRFLW = 0;
          overflow_cb(overflow_arg);
      }
  
      cortexm_isr_end();
  }