Contiki 2.5
rtimer-arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, STMicroelectronics.
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
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This file is part of the Contiki OS
31  *
32  * $Id: rtimer-arch.c,v 1.1 2010/10/25 09:03:39 salvopitru Exp $
33  */
34 /*---------------------------------------------------------------------------*/
35 /**
36 * \file
37 * Real-timer specific implementation for STM32W.
38 * \author
39 * Salvatore Pitrulli <salvopitru@users.sourceforge.net>
40 */
41 /*---------------------------------------------------------------------------*/
42 
43 
44 #include "sys/energest.h"
45 #include "sys/rtimer.h"
46 
47 
48 #define DEBUG 0
49 #if DEBUG
50 #include <stdio.h>
51 #define PRINTF(...) printf(__VA_ARGS__)
52 #else
53 #define PRINTF(...)
54 #endif
55 
56 
57 
58 static u32_t time_msb = 0; // Most significant bits of the current time.
59 
60 // time of the next rtimer event. Initially is set to the max value.
61 static rtimer_clock_t next_rtimer_time = 0;
62 
63 static u16_t saved_TIM1CFG;
64 
65 
66 /*---------------------------------------------------------------------------*/
67 void halTimer1Isr(void){
68 
69 
70  if(INT_TIM1FLAG & INT_TIMUIF){ // Overflow event.
71 
72  //PRINTF("O %4x.\r\n", TIM1_CNT);
73  //printf("OV ");
74 
75  time_msb++;
76  rtimer_clock_t now = ((rtimer_clock_t)time_msb << 16)|TIM1_CNT;
77 
78  rtimer_clock_t clock_to_wait = next_rtimer_time - now;
79 
80  if(clock_to_wait <= 0x10000 && clock_to_wait > 0){ // We must set now the Timer Compare Register.
81 
82  TIM1_CCR1 = (int16u)clock_to_wait;
83  INT_TIM1FLAG = INT_TIMCC1IF;
84  INT_TIM1CFG |= INT_TIMCC1IF; // Compare 1 interrupt enable.
85  }
86 
87  INT_TIM1FLAG = INT_TIMUIF;
88 
89  }
90 
91  else if(INT_TIM1FLAG & INT_TIMCC1IF){ // Compare event.
92 
93  INT_TIM1CFG &= ~INT_TIMCC1IF; // Disable the next compare interrupt
94 
95  PRINTF("\nCompare event %4x\r\n", TIM1_CNT);
96  PRINTF("INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG);
97  ENERGEST_ON(ENERGEST_TYPE_IRQ);
99  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
100  INT_TIM1FLAG = INT_TIMCC1IF;
101 
102  }
103 
104 }
105 /*---------------------------------------------------------------------------*/
106 void
107 rtimer_arch_init(void)
108 {
109  TIM1_CR1 = 0;
110 
111  TIM1_PSC = RT_PRESCALER;
112 
113  TIM1_ARR = 0xffff; // Counting from 0 to the maximum value.
114 
115  // Bits of TIMx_CCMR1 as default.
116 
117  TIM1_EGR = TIM_UG; // Update Generation.
118 
119  INT_TIM1FLAG = 0xffff;
120 
121  INT_TIM1CFG = INT_TIMUIF; // Update interrupt enable (interrupt on overflow).
122 
123  TIM1_CR1 = TIM_CEN; // Counter enable.
124 
125  INT_CFGSET = INT_TIM1; // Enable top level interrupt.
126 
127 }
128 /*---------------------------------------------------------------------------*/
129 void rtimer_arch_disable_irq(void)
130 {
131  ATOMIC(
132  saved_TIM1CFG = INT_TIM1CFG;
133  INT_TIM1CFG = 0;
134  )
135 }
136 /*---------------------------------------------------------------------------*/
137 void rtimer_arch_enable_irq(void)
138 {
139  INT_TIM1CFG = saved_TIM1CFG;
140 }
141 /*---------------------------------------------------------------------------*/
142 rtimer_clock_t rtimer_arch_now(void)
143 {
144  return ((rtimer_clock_t)time_msb << 16)|TIM1_CNT;
145 }
146 
147 /*---------------------------------------------------------------------------*/
148 
149 void
150 rtimer_arch_schedule(rtimer_clock_t t)
151 {
152 
153  PRINTF("rtimer_arch_schedule time %4x\r\n", /*((u32_t*)&t)+1,*/(u32_t)t);
154 
155  next_rtimer_time = t;
156 
157  rtimer_clock_t now = rtimer_arch_now();
158 
159  rtimer_clock_t clock_to_wait = t - now;
160 
161  PRINTF("now %2x\r\n", TIM1_CNT);
162  PRINTF("clock_to_wait %4x\r\n", clock_to_wait);
163 
164  if(clock_to_wait <= 0x10000){ // We must set now the Timer Compare Register.
165 
166  TIM1_CCR1 = (int16u)now + (int16u)clock_to_wait;
167  INT_TIM1FLAG = INT_TIMCC1IF;
168  INT_TIM1CFG |= INT_TIMCC1IF; // Compare 1 interrupt enable.
169 
170  PRINTF("2-INT_TIM1FLAG %2x\r\n", INT_TIM1FLAG);
171 
172  }
173  // else compare register will be set at overflow interrupt closer to the rtimer event.
174 
175 }