Contiki-NG
Loading...
Searching...
No Matches
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 cc26xx-clocks
33 * @{
34 *
35 * \defgroup cc26xx-software-clock Software Clock
36 *
37 * Implementation of the clock module for the CC26xx and CC13xx.
38 *
39 * The software clock uses the facilities provided by the AON RTC driver
40 * @{
41 *
42 * \file
43 * Software clock implementation for the TI CC13xx/CC26xx
44 */
45/*---------------------------------------------------------------------------*/
46#include "contiki.h"
47
48#include "ti-lib.h"
49/*---------------------------------------------------------------------------*/
50static volatile uint64_t count;
51
52/**< Num. fractions in sub-second. Important to cast to 64-bit */
53#define RTC_SUBSEC_FRAC ((uint64_t)1 << 32)
54/*---------------------------------------------------------------------------*/
55static void
56power_domain_on(void)
57{
58 ti_lib_prcm_power_domain_on(PRCM_DOMAIN_PERIPH);
59 while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
60 PRCM_DOMAIN_POWER_ON);
61}
62/*---------------------------------------------------------------------------*/
63void
65{
66 count = 0;
67
68 /*
69 * Here, we configure GPT0 Timer A, which we subsequently use in
70 * clock_delay_usec
71 *
72 * We need to access registers, so firstly power up the PD and then enable
73 * the clock to GPT0.
74 */
75 if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
76 PRCM_DOMAIN_POWER_ON) {
77 power_domain_on();
78 }
79
80 ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
81 ti_lib_prcm_load_set();
82 while(!ti_lib_prcm_load_get());
83
84 /* Disable both GPT0 timers */
85 HWREG(GPT0_BASE + GPT_O_CTL) &= ~(GPT_CTL_TAEN | GPT_CTL_TBEN);
86
87 /*
88 * We assume that the clock is running at 48MHz, we use GPT0 Timer A,
89 * one-shot, countdown, prescaled by 48 gives us 1 tick per usec
90 */
91 ti_lib_timer_configure(GPT0_BASE,
92 TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT);
93
94 /* Global config: split pair (2 x 16-bit wide) */
95 HWREG(GPT0_BASE + GPT_O_CFG) = TIMER_CFG_SPLIT_PAIR >> 24;
96
97 /*
98 * Pre-scale value 47 pre-scales by 48
99 *
100 * ToDo: The theoretical value here should be 47 (to provide x48 prescale)
101 * However, 49 seems to give results much closer to the desired delay
102 */
103 ti_lib_timer_prescale_set(GPT0_BASE, TIMER_B, 49);
104
105 /* GPT0 / Timer B: One shot, PWM interrupt enable */
106 HWREG(GPT0_BASE + GPT_O_TBMR) =
107 ((TIMER_CFG_B_ONE_SHOT >> 8) & 0xFF) | GPT_TBMR_TBPWMIE;
108
109 /* enable sync with radio timer */
110 HWREGBITW(AON_RTC_BASE + AON_RTC_O_CTL, AON_RTC_CTL_RTC_UPD_EN_BITN) = 1;
111}
112/*---------------------------------------------------------------------------*/
113static void
114update_clock_variable(void)
115{
116 /*
117 * RTC counter is in a 64-bits format (SEC[31:0].SUBSEC[31:0]), where SUBSEC
118 * is represented in fractions of a second (VALUE/2^32).
119 */
120 uint64_t now = ti_lib_aon_rtc_current_64_bit_value_get();
121 count = (clock_time_t)(now / (RTC_SUBSEC_FRAC / CLOCK_SECOND));
122}
123/*---------------------------------------------------------------------------*/
124clock_time_t
126{
127 update_clock_variable();
128
129 return (clock_time_t)(count & 0xFFFFFFFF);
130}
131/*---------------------------------------------------------------------------*/
132void
133clock_update(void)
134{
135 update_clock_variable();
136
137 if(etimer_pending()) {
139 }
140}
141/*---------------------------------------------------------------------------*/
142unsigned long
144{
145 return (unsigned long)ti_lib_aon_rtc_sec_get();
146}
147/*---------------------------------------------------------------------------*/
148void
149clock_wait(clock_time_t i)
150{
151 clock_time_t start;
152
153 start = clock_time();
154 while(clock_time() - start < (clock_time_t)i);
155}
156/*---------------------------------------------------------------------------*/
157void
158clock_delay_usec(uint16_t len)
159{
160 uint32_t clock_status;
161
162 if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_PERIPH) !=
163 PRCM_DOMAIN_POWER_ON) {
164 power_domain_on();
165 }
166
167 clock_status = HWREG(PRCM_BASE + PRCM_O_GPTCLKGR) & PRCM_GPIOCLKGR_CLK_EN;
168
169 ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_TIMER0);
170 ti_lib_prcm_load_set();
171 while(!ti_lib_prcm_load_get());
172
173 ti_lib_timer_load_set(GPT0_BASE, TIMER_B, len);
174 ti_lib_timer_enable(GPT0_BASE, TIMER_B);
175
176 /*
177 * Wait for TBEN to clear. CC26xxware does not provide us with a convenient
178 * function, hence the direct register access here
179 */
180 while(HWREG(GPT0_BASE + GPT_O_CTL) & GPT_CTL_TBEN);
181
182 if(clock_status == 0) {
183 ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_TIMER0);
184 ti_lib_prcm_load_set();
185 while(!ti_lib_prcm_load_get());
186 }
187}
188/*---------------------------------------------------------------------------*/
189/**
190 * \brief Obsolete delay function but we implement it here since some code
191 * still uses it
192 */
193void
194clock_delay(unsigned int i)
195{
197}
198/*---------------------------------------------------------------------------*/
199/**
200 * @}
201 * @}
202 */
unsigned long clock_seconds(void)
Get the current value of the platform seconds.
Definition clock.c:130
void clock_init(void)
Arch-specific implementation of clock_init for the cc2538.
Definition clock.c:93
void clock_delay_usec(uint16_t dt)
Delay a given number of microseconds.
Definition clock.c:150
void clock_wait(clock_time_t i)
Wait for a given number of ticks.
Definition clock.c:136
clock_time_t clock_time(void)
Get the current clock time.
Definition clock.c:118
void clock_delay(unsigned int i)
Obsolete delay function but we implement it here since some code still uses it.
Definition clock.c:164
static volatile uint64_t count
Num.
Definition clock.c:50
#define CLOCK_SECOND
A second, measured in system clock time.
Definition clock.h:103
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition etimer.c:225
void etimer_request_poll(void)
Make the event timer aware that the clock has changed.
Definition etimer.c:145
static void start(void)
Start measurement.
Header file with macros which rename TI CC26xxware functions.