mirror of
https://github.com/apache/nuttx.git
synced 2025-12-06 09:01:15 +08:00
drivers/timers/arch_alarm: Revert removal of ndelay_accurate
Some checks failed
Docker-Linux / push (push) Has been cancelled
Some checks failed
Docker-Linux / push (push) Has been cancelled
This reverts the removal of ndelay_accurate from #14450, since as mentioned in #17011, this fails to consider the `sim` architecture where CONFIG_BOARD_LOOPSPERMSEC was set to 0 because of reliance on the accurate implementations of the up_delay functions. All the commit did was remove a more accurate implementation in favour of a less accurate one. Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
This commit is contained in:
@@ -30,6 +30,14 @@
|
||||
#include <nuttx/clock.h>
|
||||
#include <nuttx/timers/arch_alarm.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CONFIG_BOARD_LOOPSPER100USEC ((CONFIG_BOARD_LOOPSPERMSEC+5)/10)
|
||||
#define CONFIG_BOARD_LOOPSPER10USEC ((CONFIG_BOARD_LOOPSPERMSEC+50)/100)
|
||||
#define CONFIG_BOARD_LOOPSPERUSEC ((CONFIG_BOARD_LOOPSPERMSEC+500)/1000)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
@@ -44,6 +52,69 @@ static clock_t g_current_tick;
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static void udelay_coarse(useconds_t microseconds)
|
||||
{
|
||||
volatile int i;
|
||||
|
||||
/* We'll do this a little at a time because we expect that the
|
||||
* CONFIG_BOARD_LOOPSPERUSEC is very inaccurate during to truncation in
|
||||
* the divisions of its calculation. We'll use the largest values that
|
||||
* we can in order to prevent significant error buildup in the loops.
|
||||
*/
|
||||
|
||||
while (microseconds > 1000)
|
||||
{
|
||||
for (i = 0; i < CONFIG_BOARD_LOOPSPERMSEC; i++)
|
||||
{
|
||||
}
|
||||
|
||||
microseconds -= 1000;
|
||||
}
|
||||
|
||||
while (microseconds > 100)
|
||||
{
|
||||
for (i = 0; i < CONFIG_BOARD_LOOPSPER100USEC; i++)
|
||||
{
|
||||
}
|
||||
|
||||
microseconds -= 100;
|
||||
}
|
||||
|
||||
while (microseconds > 10)
|
||||
{
|
||||
for (i = 0; i < CONFIG_BOARD_LOOPSPER10USEC; i++)
|
||||
{
|
||||
}
|
||||
|
||||
microseconds -= 10;
|
||||
}
|
||||
|
||||
while (microseconds > 0)
|
||||
{
|
||||
for (i = 0; i < CONFIG_BOARD_LOOPSPERUSEC; i++)
|
||||
{
|
||||
}
|
||||
|
||||
microseconds--;
|
||||
}
|
||||
}
|
||||
|
||||
static void ndelay_accurate(unsigned long nanoseconds)
|
||||
{
|
||||
struct timespec now;
|
||||
struct timespec end;
|
||||
struct timespec delta;
|
||||
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
clock_nsec2time(&delta, nanoseconds);
|
||||
clock_timespec_add(&now, &delta, &end);
|
||||
|
||||
while (clock_timespec_compare(&now, &end) < 0)
|
||||
{
|
||||
ONESHOT_CURRENT(g_oneshot_lower, &now);
|
||||
}
|
||||
}
|
||||
|
||||
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||
FAR void *arg)
|
||||
{
|
||||
@@ -74,6 +145,55 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_mdelay
|
||||
*
|
||||
* Description:
|
||||
* Delay inline for the requested number of milliseconds.
|
||||
* WARNING: NOT multi-tasking friendly
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void weak_function up_mdelay(unsigned int milliseconds)
|
||||
{
|
||||
up_udelay(USEC_PER_MSEC * milliseconds);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_udelay
|
||||
*
|
||||
* Description:
|
||||
* Delay inline for the requested number of microseconds.
|
||||
* WARNING: NOT multi-tasking friendly
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void weak_function up_udelay(useconds_t microseconds)
|
||||
{
|
||||
up_ndelay(NSEC_PER_USEC * microseconds);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: up_ndelay
|
||||
*
|
||||
* Description:
|
||||
* Delay inline for the requested number of nanoseconds.
|
||||
* WARNING: NOT multi-tasking friendly
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void weak_function up_ndelay(unsigned long nanoseconds)
|
||||
{
|
||||
if (g_oneshot_lower != NULL)
|
||||
{
|
||||
ndelay_accurate(nanoseconds);
|
||||
}
|
||||
else /* Oneshot timer hasn't been initialized yet */
|
||||
{
|
||||
udelay_coarse((nanoseconds + NSEC_PER_USEC - 1) / NSEC_PER_USEC);
|
||||
}
|
||||
}
|
||||
|
||||
void up_alarm_set_lowerhalf(FAR struct oneshot_lowerhalf_s *lower)
|
||||
{
|
||||
#ifdef CONFIG_SCHED_TICKLESS
|
||||
|
||||
@@ -35,7 +35,7 @@ set(SRCS
|
||||
# include the base delay definition (busy-loop) as a minimum-viable product. We
|
||||
# don't want the weak references to conflict.
|
||||
|
||||
if(NOT CONFIG_TIMER_ARCH)
|
||||
if(NOT CONFIG_TIMER_ARCH AND NOT CONFIG_ALARM_ARCH)
|
||||
list(APPEND SRCS delay.c)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -29,7 +29,9 @@ CSRCS += clock_perf.c clock_realtime2absticks.c
|
||||
# don't want the weak references to conflict.
|
||||
|
||||
ifneq ($(CONFIG_TIMER_ARCH),y)
|
||||
CSRCS += delay.c
|
||||
ifneq ($(CONFIG_ALARM_ARCH),y)
|
||||
CSRCS += delay.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CLOCK_TIMEKEEPING),y)
|
||||
|
||||
Reference in New Issue
Block a user