1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 #include "os/os_cputime.h"
21
22 /**
23 * This module implements cputime functionality for timers for which:
24 * a. freq is a power of 2 Hz, and
25 * b. 256 Hz <= freq < 1 MHz
26 */
27
28 #if defined(OS_CPUTIME_FREQ_PWR2)
29
30 /**
31 * @addtogroup OSKernel Operating System Kernel
32 * @{
33 * @defgroup OSCPUTime High Resolution Timers
34 * @{
35 */
36
37 /**
38 * os cputime usecs to ticks
39 *
40 * Converts the given number of microseconds into cputime ticks.
41 *
42 * @param usecs The number of microseconds to convert to ticks
43 *
44 * @return uint32_t The number of ticks corresponding to 'usecs'
45 */
46 uint32_t
os_cputime_usecs_to_ticks(uint32_t usecs)47 os_cputime_usecs_to_ticks(uint32_t usecs)
48 {
49 uint64_t ticks;
50
51 /*
52 * Faster calculation but could be off 1 full tick since we do not
53 * add residual back. Adding back the residual is commented out below, but
54 * shown.
55 */
56 ticks = (1ULL << 32) * MYNEWT_VAL(OS_CPUTIME_FREQ) / 1000000 * usecs;
57
58 /* Residual for 32768 Hz. */
59 //ticks += ((uint64_t)usecs * (1526122139+1)) >> 32;
60
61 return ticks >> 32;
62 }
63
64 /**
65 * cputime ticks to usecs
66 *
67 * Convert the given number of ticks into microseconds.
68 *
69 * @param ticks The number of ticks to convert to microseconds.
70 *
71 * @return uint32_t The number of microseconds corresponding to 'ticks'
72 *
73 * NOTE: This calculation will overflow if the value for ticks is greater
74 * than 140737488. I am not going to check that here because that many ticks
75 * is about 4222 seconds, way more than what this routine should be used for.
76 */
77 uint32_t
os_cputime_ticks_to_usecs(uint32_t ticks)78 os_cputime_ticks_to_usecs(uint32_t ticks)
79 {
80 uint32_t usecs;
81 uint32_t shift;
82 uint32_t freq;
83
84 /* Given: `freq = 2^n`, calculate `n`. */
85 /* Note: this looks like a lot of work, but gcc can optimize it away since
86 * `freq` is known at compile time.
87 */
88 freq = MYNEWT_VAL(OS_CPUTIME_FREQ);
89 shift = 0;
90 while (freq != 0) {
91 freq >>= 1;
92 shift++;
93 }
94
95 if (shift <= 7) {
96 return 0;
97 }
98 shift -= 7;
99
100 usecs = ((ticks >> shift) * 15625) + (((ticks & 0x1ff) * 15625) >> shift);
101 return usecs;
102 }
103
104 /**
105 * @} OSCPUTime
106 * @} OSKernel
107 */
108
109 #endif
110