Contiki 3.x
clock.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 platform
33  * @{
34  *
35  * \defgroup cc26xx-platforms TI CC26xx-powered Platforms
36  * @{
37  *
38  * \defgroup cc26xx The TI CC26xx and CC13xx CPUs
39  *
40  * This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are
41  * very similar, with the main difference being related to radio capability.
42  *
43  * Documentation in this group should be considered to be applicable to both
44  * families, unless explicitly stated otherwise.
45  *
46  * @{
47  *
48  * \addtogroup cc26xx-clocks
49  * @{
50  *
51  * \defgroup cc26xx-software-clock Software Clock
52  *
53  * Implementation of the clock module for the CC26xx and CC13xx.
54  *
55  * The software clock uses the facilities provided by the AON RTC driver
56  * @{
57  *
58  * \file
59  * Software clock implementation for the TI CC13xx/CC26xx
60  */
61 /*---------------------------------------------------------------------------*/
62 #include "contiki.h"
63 
64 #include "ti-lib.h"
65 /*---------------------------------------------------------------------------*/
66 static volatile uint64_t count;
67 /*---------------------------------------------------------------------------*/
68 static void
69 power_domain_on(void)
70 {
71  ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH);
72  while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
73  PRCM_DOMAIN_POWER_ON);
74 }
75 /*---------------------------------------------------------------------------*/
76 void
78 {
79  count = 0;
80 
81  /*
82  * Here, we configure GPT0 Timer A, which we subsequently use in
83  * clock_delay_usec
84  *
85  * We need to access registers, so firstly power up the PD and then enable
86  * the clock to GPT0.
87  */
88  if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
89  PRCM_DOMAIN_POWER_ON) {
90  power_domain_on();
91  }
92 
93  ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
94  ti_lib_prcm_load_set();
95  while(!ti_lib_prcm_load_get());
96 
97  /* Disable both GPT0 timers */
98  HWREG(GPT0_BASE + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
99 
100  /*
101  * We assume that the clock is running at 48MHz, we use GPT0 Timer A,
102  * one-shot, countdown, prescaled by 48 gives us 1 tick per usec
103  */
104  ti_lib_timer_configure(GPT0_BASE,
105  TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT);
106 
107  /* Global config: split pair (2 x 16-bit wide) */
108  HWREG(GPT0_BASE + GPT_O_CFG) = TIMER_CFG_SPLIT_PAIR >> 24;
109 
110  /*
111  * Pre-scale value 47 pre-scales by 48
112  *
113  * ToDo: The theoretical value here should be 47 (to provide x48 prescale)
114  * However, 49 seems to give results much closer to the desired delay
115  */
116  ti_lib_timer_prescale_set(GPT0_BASE, TIMER_B, 49);
117 
118  /* GPT0 / Timer B: One shot, PWM interrupt enable */
119  HWREG(GPT0_BASE + GPT_O_TBMR) =
120  ((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
121 }
122 /*---------------------------------------------------------------------------*/
123 static void
124 update_clock_variable(void)
125 {
126  uint32_t aon_rtc_secs_now;
127  uint32_t aon_rtc_secs_now2;
128  uint16_t aon_rtc_ticks_now;
129 
130  do {
131  aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
132  aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16;
133  aon_rtc_secs_now2 = HWREG(AON_RTC_BASE + AON_RTC_O_SEC);
134  } while(aon_rtc_secs_now != aon_rtc_secs_now2);
135 
136  /* Convert AON RTC ticks to clock tick counter */
137  count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9);
138 }
139 /*---------------------------------------------------------------------------*/
140 CCIF clock_time_t
142 {
143  update_clock_variable();
144 
145  return (clock_time_t)(count & 0xFFFFFFFF);
146 }
147 /*---------------------------------------------------------------------------*/
148 void
149 clock_update(void)
150 {
151  update_clock_variable();
152 
153  if(etimer_pending()) {
155  }
156 }
157 /*---------------------------------------------------------------------------*/
158 CCIF unsigned long
160 {
161  bool interrupts_disabled;
162  uint32_t secs_now;
163 
164  interrupts_disabled = ti_lib_int_master_disable();
165 
166  secs_now = ti_lib_aon_rtc_sec_get();
167 
168  /* Re-enable interrupts */
169  if(!interrupts_disabled) {
170  ti_lib_int_master_enable();
171  }
172 
173  return (unsigned long)secs_now;
174 }
175 /*---------------------------------------------------------------------------*/
176 void
177 clock_wait(clock_time_t i)
178 {
179  clock_time_t start;
180 
181  start = clock_time();
182  while(clock_time() - start < (clock_time_t)i);
183 }
184 /*---------------------------------------------------------------------------*/
185 void
186 clock_delay_usec(uint16_t len)
187 {
188  uint32_t clock_status;
189 
190  if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
191  PRCM_DOMAIN_POWER_ON) {
192  power_domain_on();
193  }
194 
195  clock_status = HWREG(PRCM_BASE + PRCM_O_GPTCLKGR) & PRCM_GPIOCLKGR_CLK_EN;
196 
197  ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
198  ti_lib_prcm_load_set();
199  while(!ti_lib_prcm_load_get());
200 
201  ti_lib_timer_load_set(GPT0_BASE, TIMER_B, len);
202  ti_lib_timer_enable(GPT0_BASE, TIMER_B);
203 
204  /*
205  * Wait for TBEN to clear. CC26xxware does not provide us with a convenient
206  * function, hence the direct register access here
207  */
208  while(HWREG(GPT0_BASE + GPT_O_CTL) & GPT_CTL_TBEN);
209 
210  if(clock_status == 0) {
211  ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0);
212  ti_lib_prcm_load_set();
213  while(!ti_lib_prcm_load_get());
214  }
215 }
216 /*---------------------------------------------------------------------------*/
217 /**
218  * \brief Obsolete delay function but we implement it here since some code
219  * still uses it
220  */
221 void
222 clock_delay(unsigned int i)
223 {
224  clock_delay_usec(i);
225 }
226 /*---------------------------------------------------------------------------*/
227 /**
228  * @}
229  * @}
230  * @}
231  * @}
232  * @}
233  */
static void start(void)
Start measurement.
Header file with macros which rename TI CC26xxware functions.
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition: etimer.c:145
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition: etimer.c:231
clock_time_t clock_time(void)
Get the current clock time.
Definition: clock.c:41
void clock_init()
Initialize the clock library.
Definition: clock.c:76
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
static volatile clock_time_t count
These routines define the AVR-specific calls declared in /core/sys/clock.h CLOCK_SECOND is the number...
Definition: clock.c:80
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
Definition: clock.c:170
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition: clock.c:162
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Definition: clock.c:54
void clock_delay_usec(uint16_t usec)
Delay a given number of microseconds.
Definition: clock.c:94