Contiki-NG
Loading...
Searching...
No Matches
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 */
51void clock_update(void);
52
53static 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/*---------------------------------------------------------------------------*/
70void
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/*---------------------------------------------------------------------------*/
110rtimer_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/*---------------------------------------------------------------------------*/
124void
125soc_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/*---------------------------------------------------------------------------*/
136rtimer_clock_t
137soc_rtc_last_isr_time(void)
138{
139 return last_isr_time;
140}
141/*---------------------------------------------------------------------------*/
142/* The AON RTC interrupt handler */
143void
144soc_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;
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_init(void)
Initialise the CC13XX/CC26XX AON RTC module.
Definition soc-rtc.c:71
rtimer_clock_t soc_rtc_get_next_trigger()
Return the time of the next scheduled rtimer event.
Definition soc-rtc.c:111
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
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition rtimer.c:78
#define RTIMER_NOW()
Get the current clock time.
Definition rtimer.h:187
Header file for the real-time timer module.
Header file with macros which rename TI CC26xxware functions.