Blame view

RIOT/cpu/nrf51/periph/rtt.c 2.48 KB
fb11e647   vrobic   reseau statique a...
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
  /*
   * Copyright (C) 2014 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.
   */
  
  /**
   * @ingroup     cpu_nrf51822
   * @{
   *
   * @file
   * @brief       Real-time timer driver implementation
   *
   * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
   *
   * @}
   */
  
  #include <stdlib.h>
  #include <stdio.h>
  
  #include "cpu.h"
  #include "board.h"
  #include "periph_conf.h"
  #include "periph/rtt.h"
  
  /* guard file in case no RTC device was specified */
  #if RTT_NUMOF
  
  /*
   * @brief Callback for the active alarm
   */
  static rtt_cb_t alarm_cb;
  
  /**
   * @brief Argument for the active alarm callback
   */
  static void *alarm_arg;
  
  /**
   * @brief Callback for the overflow event
   */
  static rtt_cb_t overflow_cb;
  
  /**
   * @brief Argument for the overflow callback
   */
  static void *overflow_arg;
  
  void rtt_init(void)
  {
      rtt_poweron();
  
      /* configure interrupt */
      NVIC_SetPriority(RTT_IRQ, RTT_IRQ_PRIO);
      NVIC_EnableIRQ(RTT_IRQ);
  
      /* set prescaler */
      RTT_DEV->PRESCALER = RTT_PRESCALER;
  
      /* enable the low-frequency clock */
      NRF_CLOCK->TASKS_LFCLKSTART = 1;
  
      /* start the actual RTT thing */
      RTT_DEV->TASKS_START = 1;
  }
  
  void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
  {
      overflow_cb = cb;
      overflow_arg = arg;
      RTT_DEV->INTENSET = RTC_INTENSET_OVRFLW_Msk;
  }
  
  void rtt_clear_overflow_cb(void)
  {
      RTT_DEV->INTENCLR = RTC_INTENCLR_OVRFLW_Msk;
  }
  
  uint32_t rtt_get_counter(void)
  {
      return RTT_DEV->COUNTER;
  }
  
  void rtt_set_counter(uint32_t counter)
  {
      (void) counter;
      /* not supported for the NRF51822? -> could not find out how to do this */
  }
  
  void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
  {
      alarm_cb = cb;
      alarm_arg = arg;
      RTT_DEV->CC[0] = (alarm & RTT_MAX_VALUE);
      RTT_DEV->INTENSET = RTC_INTENSET_COMPARE0_Msk;
  }
  
  uint32_t rtt_get_alarm(void)
  {
      return RTT_DEV->CC[0];
  }
  
  void rtt_clear_alarm(void)
  {
      RTT_DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
  }
  
  void rtt_poweron(void)
  {
      RTT_DEV->POWER = 1;
  }
  
  void rtt_poweroff(void)
  {
      RTT_DEV->POWER = 0;
  }
  
  void RTT_ISR(void)
  {
      if (RTT_DEV->EVENTS_COMPARE[0] == 1) {
          RTT_DEV->EVENTS_COMPARE[0] = 0;
          RTT_DEV->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
          alarm_cb(alarm_arg);
      }
      if (RTT_DEV->EVENTS_OVRFLW == 1) {
          RTT_DEV->EVENTS_OVRFLW = 0;
          overflow_cb(overflow_arg);
      }
      cortexm_isr_end();
  }
  
  #endif /* RTT_NUMOF */