Contiki 3.x
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 "sys/energest.h"
41 #include "rtimer.h"
42 #include "lpm.h"
43 
44 #include "ti-lib.h"
45 
46 #include <stdint.h>
47 #include <stdbool.h>
48 /*---------------------------------------------------------------------------*/
49 #define soc_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__)
50 /*---------------------------------------------------------------------------*/
51 /* Prototype of a function in clock.c. Called every time the handler fires */
52 void clock_update(void);
53 
54 static rtimer_clock_t last_isr_time;
55 /*---------------------------------------------------------------------------*/
56 #define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND)
57 #define MULTIPLE_512_MASK 0xFFFFFE00
58 /*---------------------------------------------------------------------------*/
59 /*
60  * Used to test timer wraparounds.
61  *
62  * Set to 0xFFFFFFFA to test AON RTC second counter wraparound
63  * Set to 0xFFFA to test AON RTC 16.16 format wraparound
64  */
65 #ifdef SOC_RTC_CONF_START_TICK_COUNT
66 #define SOC_RTC_START_TICK_COUNT SOC_RTC_CONF_START_TICK_COUNT
67 #else
68 #define SOC_RTC_START_TICK_COUNT 0
69 #endif
70 /*---------------------------------------------------------------------------*/
71 void
73 {
74  bool interrupts_disabled;
75  uint32_t next;
76 
77  /* Disable and clear interrupts */
78  interrupts_disabled = ti_lib_int_master_disable();
79 
80  ti_lib_aon_rtc_disable();
81 
82  ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
83  ti_lib_aon_rtc_event_clear(AON_RTC_CH1);
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_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1);
89 
90  HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT;
91 
92  next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT;
93 
94  /* Configure channel 1 to start generating clock ticks. First tick at 512 */
95  ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
96 
97  /* Enable channel 1 and the RTC */
98  ti_lib_aon_rtc_channel_enable(AON_RTC_CH1);
99  ti_lib_aon_rtc_enable();
100 
101  ti_lib_int_enable(INT_AON_RTC);
102 
103  /* Re-enable interrupts */
104  if(!interrupts_disabled) {
105  ti_lib_int_master_enable();
106  }
107 }
108 /*---------------------------------------------------------------------------*/
109 rtimer_clock_t
111 {
112  rtimer_clock_t ch1 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH1);
113 
114  if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH0_EN) {
115  rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
116 
117  return RTIMER_CLOCK_LT(ch0, ch1) ? ch0 : ch1;
118  }
119 
120  return ch1;
121 }
122 /*---------------------------------------------------------------------------*/
123 void
124 soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
125 {
126  if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1)) {
127  return;
128  }
129 
130  /* Set the channel to fire a one-shot compare event at time==ticks */
131  ti_lib_aon_rtc_compare_value_set(channel, ticks);
132  ti_lib_aon_rtc_channel_enable(channel);
133 }
134 /*---------------------------------------------------------------------------*/
135 rtimer_clock_t
136 soc_rtc_last_isr_time(void)
137 {
138  return last_isr_time;
139 }
140 /*---------------------------------------------------------------------------*/
141 /* The AON RTC interrupt handler */
142 void
143 soc_rtc_isr(void)
144 {
145  uint32_t next;
146 
147  ENERGEST_ON(ENERGEST_TYPE_IRQ);
148 
149  last_isr_time = RTIMER_NOW();
150 
151  /* Adjust the s/w tick counter irrespective of which event trigger this */
152  clock_update();
153 
154  if(ti_lib_aon_rtc_event_get(AON_RTC_CH1)) {
155  HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1;
156 
157  /*
158  * We need to keep ticking while we are awake, so we schedule the next
159  * event on the next 512 tick boundary. If we drop to deep sleep before it
160  * happens, lpm_drop() will reschedule us in the 'distant' future
161  */
162  next = ((ti_lib_aon_rtc_current_compare_value_get() + 5) +
163  COMPARE_INCREMENT) & MULTIPLE_512_MASK;
164  ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next);
165  }
166 
167  if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
168  ti_lib_aon_rtc_channel_disable(AON_RTC_CH0);
169  HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0;
170  rtimer_run_next();
171  }
172 
173  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
174 }
175 /*---------------------------------------------------------------------------*/
176 /** @} */
Header file for the real-time timer module.
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:124
Header file with macros which rename TI CC26xxware functions.
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
Header file for the energy estimation mechanism
void soc_rtc_init(void)
Initialise the CC13XX/CC26XX AON RTC module.
Definition: soc-rtc.c:72
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition: rtimer.c:92
rtimer_clock_t soc_rtc_get_next_trigger()
Return the time of the next scheduled rtimer event.
Definition: soc-rtc.c:110