Contiki-NG
Loading...
Searching...
No Matches
rtimer-arch.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018, 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 * \addtogroup cc13xx-cc26xx-rtimer
32 * @{
33 *
34 * \file
35 * Implementation of the rtimer driver for CC13xx/CC26xx.
36 * \author
37 * Edvard Pettersen <e.pettersen@ti.com>
38 */
39/*---------------------------------------------------------------------------*/
40#include "contiki.h"
41/*---------------------------------------------------------------------------*/
42#include <ti/devices/DeviceFamily.h>
43#include DeviceFamily_constructPath(driverlib/aon_event.h)
44#include DeviceFamily_constructPath(driverlib/aon_rtc.h)
45#include DeviceFamily_constructPath(driverlib/interrupt.h)
46
47#include <ti/drivers/dpl/ClockP.h>
48#include <ti/drivers/dpl/HwiP.h>
49/*---------------------------------------------------------------------------*/
50#include <stddef.h>
51#include <stdint.h>
52/*---------------------------------------------------------------------------*/
53#define HWIP_RTC_CH AON_RTC_CH0
54#define RTIMER_RTC_CH AON_RTC_CH1
55/*---------------------------------------------------------------------------*/
56typedef void (*isr_fxn_t)(void);
57typedef void (*hwi_dispatch_fxn_t)(void);
58
59static hwi_dispatch_fxn_t hwi_dispatch_fxn;
60/*---------------------------------------------------------------------------*/
61/**
62 * \brief Stub function used when creating the dummy clock object.
63 */
64static void
65rtimer_clock_stub(uintptr_t unused)
66{
67 (void)unused;
68 /* do nothing */
69}
70/*---------------------------------------------------------------------------*/
71/**
72 * \brief The Man-in-the-Middle ISR hook for the HWI dispatch ISR. This
73 * will be the ISR dispatched when INT_AON_RTC_COMB is triggered,
74 * and will either dispatch the interrupt to the rtimer driver or
75 * the HWI driver, depending on which event triggered the interrupt.
76 */
77static void
79{
80 if(AONRTCEventGet(RTIMER_RTC_CH)) {
81 AONRTCEventClear(RTIMER_RTC_CH);
82 AONRTCChannelDisable(RTIMER_RTC_CH);
83
85 }
86 /*
87 * HWI Dispatch clears the interrupt. If HWI wasn't triggered, clear
88 * the interrupt manually.
89 */
90 if(AONRTCEventGet(HWIP_RTC_CH)) {
91 hwi_dispatch_fxn();
92 } else {
93 IntPendClear(INT_AON_RTC_COMB);
94 }
95}
96/*---------------------------------------------------------------------------*/
97/**
98 * \brief TODO
99 */
100void
102{
103 uintptr_t key;
104 ClockP_Struct clk_object;
105 ClockP_Params clk_params;
106 volatile isr_fxn_t *ramvec_table;
107
108 key = HwiP_disable();
109
110 /*
111 * Create a dummy clock to guarantee the RAM vector table is initialized.
112 *
113 * Creating a dummy clock will trigger initialization of TimerP, which
114 * subsequently initializes the driverlib/interrupt.h module. It is the
115 * interrupt module that initializes the RAM vector table.
116 *
117 * It is safe to destruct the Clock object immediately afterwards.
118 */
119 ClockP_Params_init(&clk_params);
120 ClockP_construct(&clk_object, rtimer_clock_stub, 0, &clk_params);
121 ClockP_destruct(&clk_object);
122
123 /* Try to access the RAM vector table. */
124 ramvec_table = (isr_fxn_t *)HWREG(NVIC_VTABLE);
125 if(!ramvec_table) {
126 /*
127 * Unable to find the RAM vector table is a serious fault.
128 * Spin-lock forever.
129 */
130 for(;;) { /* hang */ }
131 }
132
133 /*
134 * The HWI Dispatch ISR is located at interrupt number INT_AON_RTC_COMB
135 * in the RAM vector table. Fetch and store it.
136 */
137 hwi_dispatch_fxn = (hwi_dispatch_fxn_t)ramvec_table[INT_AON_RTC_COMB];
138 if(!hwi_dispatch_fxn) {
139 /*
140 * Unable to find the HWI dispatch ISR in the RAM vector table is
141 * a serious fault. Spin-lock forever.
142 */
143 for(;;) { /* hang */ }
144 }
145
146 /*
147 * Override the INT_AON_RTC_COMB interrupt number with our own ISR hook,
148 * which will act as a man-in-the-middle ISR for the HWI dispatch.
149 */
150 IntRegister(INT_AON_RTC_COMB, rtimer_isr_hook);
151 IntPrioritySet(INT_AON_RTC_COMB, INT_PRI_LEVEL7);
152
153 AONEventMcuWakeUpSet(AON_EVENT_MCU_WU3, AON_EVENT_RTC_CH1);
154 AONRTCCombinedEventConfig(HWIP_RTC_CH | RTIMER_RTC_CH);
155
156 HwiP_restore(key);
157}
158/*---------------------------------------------------------------------------*/
159/**
160
161 * This function schedules a one-shot event with the AON RTC.
162 *
163 * This functions converts \p t to a value suitable for the AON RTC.
164 */
165void
166rtimer_arch_schedule(rtimer_clock_t t)
167{
168 /* Convert the rtimer tick value to a value suitable for the AON RTC */
169 AONRTCCompareValueSet(RTIMER_RTC_CH, (uint32_t)t);
170 AONRTCChannelEnable(RTIMER_RTC_CH);
171}
172/*---------------------------------------------------------------------------*/
173/**
174 * \brief Returns the current real-time clock time.
175 * \return The current rtimer time in ticks.
176 *
177 * The value is read from the AON RTC counter and converted to a
178 * number of rtimer ticks.
179 */
180rtimer_clock_t
182{
183 return (rtimer_clock_t)AONRTCCurrentCompareValueGet();
184}
185/*---------------------------------------------------------------------------*/
186/** @} */
static void rtimer_clock_stub(uintptr_t unused)
Stub function used when creating the dummy clock object.
Definition rtimer-arch.c:65
static void rtimer_isr_hook(void)
The Man-in-the-Middle ISR hook for the HWI dispatch ISR.
Definition rtimer-arch.c:78
void rtimer_arch_init(void)
We don't need to explicitly initialise anything but this routine is required by the API.
Definition rtimer-arch.c:59
rtimer_clock_t rtimer_arch_now()
Returns the current real-time clock time.
void rtimer_arch_schedule(rtimer_clock_t t)
Schedules an rtimer task to be triggered at time t.
Definition rtimer-arch.c:65
void rtimer_run_next(void)
Execute the next real-time task and schedule the next task, if any.
Definition rtimer.c:78