3030#include <nuttx/clock.h>
3131#include <nuttx/timers/arch_alarm.h>
3232
33+ /****************************************************************************
34+ * Pre-processor Definitions
35+ ****************************************************************************/
36+
37+ #define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10)
38+ #define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100)
39+ #define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000)
40+
3341/****************************************************************************
3442 * Private Data
3543 ****************************************************************************/
@@ -44,6 +52,69 @@ static clock_t g_current_tick;
4452 * Private Functions
4553 ****************************************************************************/
4654
55+ static void udelay_coarse (useconds_t microseconds )
56+ {
57+ volatile int i ;
58+
59+ /* We'll do this a little at a time because we expect that the
60+ * CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in
61+ * the divisions of its calculation. We'll use the largest values that
62+ * we can in order to prevent significant error buildup in the loops.
63+ */
64+
65+ while (microseconds > 1000 )
66+ {
67+ for (i = 0 ; i < CONFIG_BOARD_LOOPSPERMSEC ; i ++ )
68+ {
69+ }
70+
71+ microseconds -= 1000 ;
72+ }
73+
74+ while (microseconds > 100 )
75+ {
76+ for (i = 0 ; i < CONFIG_BOARD_LOOPSPER100USEC ; i ++ )
77+ {
78+ }
79+
80+ microseconds -= 100 ;
81+ }
82+
83+ while (microseconds > 10 )
84+ {
85+ for (i = 0 ; i < CONFIG_BOARD_LOOPSPER10USEC ; i ++ )
86+ {
87+ }
88+
89+ microseconds -= 10 ;
90+ }
91+
92+ while (microseconds > 0 )
93+ {
94+ for (i = 0 ; i < CONFIG_BOARD_LOOPSPERUSEC ; i ++ )
95+ {
96+ }
97+
98+ microseconds -- ;
99+ }
100+ }
101+
102+ static void ndelay_accurate (unsigned long nanoseconds )
103+ {
104+ struct timespec now ;
105+ struct timespec end ;
106+ struct timespec delta ;
107+
108+ ONESHOT_CURRENT (g_oneshot_lower , & now );
109+ clock_nsec2time (& delta , nanoseconds );
110+ clock_timespec_add (& now , & delta , & end );
111+
112+ while (clock_timespec_compare (& now , & end ) < 0 )
113+ {
114+ ONESHOT_CURRENT (g_oneshot_lower , & now );
115+ }
116+ }
117+
47118static void oneshot_callback (FAR struct oneshot_lowerhalf_s * lower ,
48119 FAR void * arg )
49120{
@@ -74,6 +145,55 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
74145 * Public Functions
75146 ****************************************************************************/
76147
148+ /****************************************************************************
149+ * Name: up_mdelay
150+ *
151+ * Description:
152+ * Delay inline for the requested number of milliseconds.
153+ * WARNING: NOT multi-tasking friendly
154+ *
155+ ****************************************************************************/
156+
157+ void weak_function up_mdelay (unsigned int milliseconds )
158+ {
159+ up_udelay (USEC_PER_MSEC * milliseconds );
160+ }
161+
162+ /****************************************************************************
163+ * Name: up_udelay
164+ *
165+ * Description:
166+ * Delay inline for the requested number of microseconds.
167+ * WARNING: NOT multi-tasking friendly
168+ *
169+ ****************************************************************************/
170+
171+ void weak_function up_udelay (useconds_t microseconds )
172+ {
173+ up_ndelay (NSEC_PER_USEC * microseconds );
174+ }
175+
176+ /****************************************************************************
177+ * Name: up_ndelay
178+ *
179+ * Description:
180+ * Delay inline for the requested number of nanoseconds.
181+ * WARNING: NOT multi-tasking friendly
182+ *
183+ ****************************************************************************/
184+
185+ void weak_function up_ndelay (unsigned long nanoseconds )
186+ {
187+ if (g_oneshot_lower != NULL )
188+ {
189+ ndelay_accurate (nanoseconds );
190+ }
191+ else /* Oneshot timer hasn't been initialized yet */
192+ {
193+ udelay_coarse ((nanoseconds + NSEC_PER_USEC - 1 ) / NSEC_PER_USEC );
194+ }
195+ }
196+
77197void up_alarm_set_lowerhalf (FAR struct oneshot_lowerhalf_s * lower )
78198{
79199#ifdef CONFIG_SCHED_TICKLESS
0 commit comments