Contiki-NG
soc-rtc.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
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
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*---------------------------------------------------------------------------*/
31 /**
32  * \addtogroup cc13xx-cc26xx-rtc
33  * @{
34  *
35  * \file
36  * Implementation of the CC13xx/CC26xx AON RTC driver
37  */
38 /*---------------------------------------------------------------------------*/
39 #include "contiki.h"
40 #include "rtimer.h"
41 #include "lpm.h"
42 
43 #include "ti-lib.h"
44 
45 #include <stdint.h>
46 #include <stdbool.h>
47 /*---------------------------------------------------------------------------*/
48 #define soc_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__)
49 /*---------------------------------------------------------------------------*/
50 /* Prototype of a function in clock.c. Called every time the handler fires */
51 void clock_update(void);
52 
53 static rtimer_clock_t last_isr_time;
54 /*---------------------------------------------------------------------------*/
55 #define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND)
56 #define MULTIPLE_512_MASK 0xFFFFFE00
57 /*---------------------------------------------------------------------------*/
58 /*
59  * Used to test timer wraparounds.
60  *
61  * Set to 0xFFFFFFFA to test AON RTC second counter wraparound
62  * Set to 0xFFFA to test AON RTC 16.16 format wraparound
63  */
64 #ifdef SOC_RTC_CONF_START_TICK_COUNT
65 #define SOC_RTC_START_TICK_COUNT SOC_RTC_CONF_START_TICK_COUNT
66 #else
67 #define SOC_RTC_START_TICK_COUNT 0
68 #endif
69 /*---------------------------------------------------------------------------*/
70 void
72 {
73  bool interrupts_disabled;
74  uint32_t next;
75 
76  /* Disable and clear interrupts */
77  interrupts_disabled = ti_lib_int_master_disable();
78 
79  ti_lib_aon_rtc_disable();
80 
81  ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
82  ti_lib_aon_rtc_event_clear(AON_RTC_CH1);
83  ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
84 
85  /* Setup the wakeup event */
86  ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0);
87  ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1);
88  ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_RTC_CH2);
89  ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1 | AON_RTC_CH2);
90 
91  HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT;
92 
93  next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT;
94 
95  /* Configure channel 1 to start generating clock ticks. First tick at 512 */
96  ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
97 
98  /* Enable channel 1 and the RTC */
99  ti_lib_aon_rtc_channel_enable(AON_RTC_CH1);
100  ti_lib_aon_rtc_enable();
101 
102  ti_lib_int_enable(INT_AON_RTC_COMB);
103 
104  /* Re-enable interrupts */
105  if(!interrupts_disabled) {
106  ti_lib_int_master_enable();
107  }
108 }
109 /*---------------------------------------------------------------------------*/
110 rtimer_clock_t
112 {
113  rtimer_clock_t ch1 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH1);
114 
115  if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH0_EN) {
116  rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
117 
118  return RTIMER_CLOCK_LT(ch0, ch1) ? ch0 : ch1;
119  }
120 
121  return ch1;
122 }
123 /*---------------------------------------------------------------------------*/
124 void
125 soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
126 {
127  if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1) && (channel != AON_RTC_CH2)) {
128  return;
129  }
130 
131  /* Set the channel to fire a one-shot compare event at time==ticks */
132  ti_lib_aon_rtc_compare_value_set(channel, ticks);
133  ti_lib_aon_rtc_channel_enable(channel);
134 }
135 /*---------------------------------------------------------------------------*/
136 rtimer_clock_t
137 soc_rtc_last_isr_time(void)
138 {
139  return last_isr_time;
140 }
141 /*---------------------------------------------------------------------------*/
142 /* The AON RTC interrupt handler */
143 void
144 soc_rtc_isr(void)
145 {
146  uint32_t next;
147 
148  last_isr_time = RTIMER_NOW();
149 
150  /* Adjust the s/w tick counter irrespective of which event trigger this */
151  clock_update();
152 
153  if(ti_lib_aon_rtc_event_get(AON_RTC_CH1)) {
154  HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1;
155 
156  /*
157  * We need to keep ticking while we are awake, so we schedule the next
158  * event on the next 512 tick boundary. If we drop to deep sleep before it
159  * happens, lpm_drop() will reschedule us in the 'distant' future
160  */
161  next = ((ti_lib_aon_rtc_current_compare_value_get() + 5) +
162  COMPARE_INCREMENT) & MULTIPLE_512_MASK;
163  ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
164  }
165 
166  if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
167  ti_lib_aon_rtc_channel_disable(AON_RTC_CH0);
168  HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0;
169  rtimer_run_next();
170  }
171 
172  if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) {
173  /* after sleep; since a rtimer is already scheduled, do nothing */
174  ti_lib_aon_rtc_channel_disable(AON_RTC_CH2);
175  HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2;
176  }
177 }
178 /*---------------------------------------------------------------------------*/
179 /** @} */
void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
Schedule an AON RTC channel 0 one-shot compare event.
Definition: soc-rtc.c:125
Header file with macros which rename TI CC26xxware functions.
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:185
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition: rtimer.c:92
void soc_rtc_init(void)
Initialise the CC13XX/CC26XX AON RTC module.
Definition: soc-rtc.c:71
Header file for the real-time timer module.
rtimer_clock_t soc_rtc_get_next_trigger()
Return the time of the next scheduled rtimer event.
Definition: soc-rtc.c:111