thermferm/delay.c

changeset 652
16d3d4b58b5b
equal deleted inserted replaced
651:da166cb8470f 652:16d3d4b58b5b
1 /**
2 * @file delay.c
3 * #brief Thread friendly delay functions.
4 *
5 * Copyright (C) 2024
6 *
7 * Michiel Broek <mbroek at mbse dot eu>
8 *
9 * This file is part of the mbsePi-apps
10 *
11 * This is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2, or (at your option) any
14 * later version.
15 *
16 * mbsePi-apps is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with ThermFerm; see the file COPYING. If not, write to the Free
23 * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24 */
25
26 #include "delay.h"
27 #include "thermferm.h"
28
29
30 void delay (unsigned int howLong)
31 {
32 struct timespec sleeper, dummy ;
33
34 sleeper.tv_sec = (time_t)(howLong / 1000) ;
35 sleeper.tv_nsec = (long)(howLong % 1000) * 1000000 ;
36
37 nanosleep (&sleeper, &dummy) ;
38 }
39
40
41
42
43 /**
44 * @brief mDelay Delay number of milliseconds.
45 * @param howLong The number of milliseconds.
46 */
47 void mDelay(unsigned int howLong)
48 {
49 struct timespec sleeper ;
50 unsigned int mSecs = howLong % 1000 ;
51 unsigned int wSecs = howLong / 1000 ;
52
53 /**/ if (howLong == 0)
54 return ;
55 else {
56 sleeper.tv_sec = wSecs ;
57 sleeper.tv_nsec = (long)(mSecs * 1000000L) ;
58 nanosleep (&sleeper, NULL) ;
59 }
60 }
61
62
63 /*
64 * Code from wiringPi, Gordon.
65 *
66 * delayMicroseconds:
67 * This is somewhat intersting. It seems that on the Pi, a single call
68 * to nanosleep takes some 80 to 130 microseconds anyway, so while
69 * obeying the standards (may take longer), it's not always what we
70 * want!
71 *
72 * So what I'll do now is if the delay is less than 100uS we'll do it
73 * in a hard loop, watching a built-in counter on the ARM chip. This is
74 * somewhat sub-optimal in that it uses 100% CPU, something not an issue
75 * in a microcontroller, but under a multi-tasking, multi-user OS, it's
76 * wastefull, however we've no real choice )-:
77 *
78 * Plan B: It seems all might not be well with that plan, so changing it
79 * to use gettimeofday () and poll on that instead...
80 *********************************************************************************
81 */
82 void delayMicrosecondsHard (unsigned int howLong)
83 {
84 struct timeval tNow, tLong, tEnd ;
85
86 gettimeofday (&tNow, NULL) ;
87 tLong.tv_sec = howLong / 1000000 ;
88 tLong.tv_usec = howLong % 1000000 ;
89 timeradd (&tNow, &tLong, &tEnd) ;
90
91 while (timercmp (&tNow, &tEnd, <))
92 gettimeofday (&tNow, NULL) ;
93 }
94
95
96 /**
97 * @brief uDelay Delays a number of microseconds. Also used to replace usleep().
98 * @param howLong The number is microseconds.
99 */
100 void uDelay(unsigned int howLong)
101 {
102 struct timespec sleeper ;
103 unsigned int uSecs = howLong % 1000000 ;
104 unsigned int wSecs = howLong / 1000000 ;
105
106 /**/ if (howLong == 0)
107 return ;
108 else if (howLong < 100)
109 delayMicrosecondsHard(howLong) ;
110 else {
111 sleeper.tv_sec = wSecs ;
112 sleeper.tv_nsec = (long)(uSecs * 1000L) ;
113 nanosleep (&sleeper, NULL) ;
114 }
115 }
116
117

mercurial