mirror of
https://github.com/apache/nuttx.git
synced 2025-12-10 20:24:51 +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/clock.h>
|
||||||
#include <nuttx/timers/arch_alarm.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
|
* Private Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@@ -44,6 +52,69 @@ static clock_t g_current_tick;
|
|||||||
* Private Functions
|
* 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,
|
static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
||||||
FAR void *arg)
|
FAR void *arg)
|
||||||
{
|
{
|
||||||
@@ -74,6 +145,55 @@ static void oneshot_callback(FAR struct oneshot_lowerhalf_s *lower,
|
|||||||
* Public Functions
|
* 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)
|
void up_alarm_set_lowerhalf(FAR struct oneshot_lowerhalf_s *lower)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_TICKLESS
|
#ifdef CONFIG_SCHED_TICKLESS
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ set(SRCS
|
|||||||
# include the base delay definition (busy-loop) as a minimum-viable product. We
|
# include the base delay definition (busy-loop) as a minimum-viable product. We
|
||||||
# don't want the weak references to conflict.
|
# 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)
|
list(APPEND SRCS delay.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ CSRCS += clock_perf.c clock_realtime2absticks.c
|
|||||||
# don't want the weak references to conflict.
|
# don't want the weak references to conflict.
|
||||||
|
|
||||||
ifneq ($(CONFIG_TIMER_ARCH),y)
|
ifneq ($(CONFIG_TIMER_ARCH),y)
|
||||||
CSRCS += delay.c
|
ifneq ($(CONFIG_ALARM_ARCH),y)
|
||||||
|
CSRCS += delay.c
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_CLOCK_TIMEKEEPING),y)
|
ifeq ($(CONFIG_CLOCK_TIMEKEEPING),y)
|
||||||
|
|||||||
Reference in New Issue
Block a user