1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #5608 from gebart/pr/xtimer-ticks

xtimer: Allow arbitrary timer frequency, second attempt
This commit is contained in:
Francisco Acosta 2016-11-29 23:00:31 +01:00 committed by GitHub
commit 84d0d61279
64 changed files with 876 additions and 275 deletions

View File

@ -535,6 +535,7 @@ endif
ifneq (,$(filter xtimer,$(USEMODULE)))
FEATURES_REQUIRED += periph_timer
USEMODULE += div
endif
ifneq (,$(filter saul_reg,$(USEMODULE)))

View File

@ -73,6 +73,7 @@ extern "C" {
*/
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (2)
#define XTIMER_HZ (250000UL)
#define XTIMER_BACKOFF (40)
/** @} */

View File

@ -69,6 +69,7 @@ extern "C" {
*/
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (2)
#define XTIMER_HZ (250000UL)
#define XTIMER_BACKOFF (40)
/** @} */

View File

@ -401,7 +401,7 @@ uint8_t writeRingBuff(int16_t *value)
/* measuring temperature dependent internal sample rate of SMB380 */
if (smb380_mode == SMB380_CONTINOUS) {
tickLastSample = xtimer_now();
tickLastSample = xtimer_now_usec();
tickCurrentSamples++;
}
@ -1030,7 +1030,7 @@ void SMB380_enableNewDataInt(void)
SMB380_ssp_read();
SMB380_Unprepare();
// measuring temperature dependent internal sample rate of SMB380
tickStart = xtimer_now();
tickStart = xtimer_now_usec();
tickCurrentSamples = 0;
irq_restore(cpsr);
}

View File

@ -79,6 +79,8 @@ extern "C" {
#define XTIMER_DEV (0)
#define XTIMER_CHAN (0)
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (4)
#define XTIMER_HZ (16000000UL)
#define XTIMER_BACKOFF (50)
#define XTIMER_ISR_BACKOFF (40)
/** @} */

View File

@ -67,6 +67,8 @@
#define XTIMER_DEV (0)
#define XTIMER_CHAN (0)
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (4)
#define XTIMER_HZ (16000000UL)
#define XTIMER_BACKOFF (50)
#define XTIMER_ISR_BACKOFF (40)
/** @} */

View File

@ -80,6 +80,8 @@
#define XTIMER_DEV (0)
#define XTIMER_CHAN (0)
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (4)
#define XTIMER_HZ (16000000UL)
#define XTIMER_BACKOFF (50)
#define XTIMER_ISR_BACKOFF (40)
/** @} */

View File

@ -169,8 +169,8 @@ extern "C" {
*/
#define XTIMER_WIDTH (16)
#define XTIMER_SHIFT (4)
#define XTIMER_HZ (62500UL)
#define XTIMER_BACKOFF (40)
#define XTIMER_TICKS_INIT (921600ul)
/** @} */
/**

View File

@ -84,7 +84,7 @@ int __attribute__((used)) sched_run(void)
}
#ifdef MODULE_SCHEDSTATISTICS
unsigned long time = xtimer_now();
unsigned long time = _xtimer_now();
#endif
if (active_thread) {

View File

@ -163,10 +163,10 @@ interrupt(PORT1_VECTOR) __attribute__((naked)) port1_isr(void)
/* check interrupt source */
if (debounce_flags[0] & p1ifg) {
/* check if bouncing */
diff = xtimer_now() - debounce_time[0][ifg_num];
diff = xtimer_now_usec() - debounce_time[0][ifg_num];
if (diff > DEBOUNCE_TIMEOUT) {
debounce_time[0][ifg_num] = xtimer_now();
debounce_time[0][ifg_num] = xtimer_now_usec();
if (cb[0][ifg_num] != NULL) {
cb[0][ifg_num]();
@ -208,10 +208,10 @@ interrupt(PORT2_VECTOR) __attribute__((naked)) port2_isr(void)
/* check interrupt source */
if (debounce_flags[1] & p2ifg) {
/* check if bouncing */
diff = xtimer_now() - debounce_time[1][ifg_num];
diff = xtimer_now_usec() - debounce_time[1][ifg_num];
if (diff > DEBOUNCE_TIMEOUT) {
debounce_time[1][ifg_num] = xtimer_now();
debounce_time[1][ifg_num] = xtimer_now_usec();
c1++;
if (cb[1][ifg_num] != NULL) {

View File

@ -109,12 +109,12 @@ uint16_t adc_read(uint8_t channel)
/* switch channel, start A/D convert */
AD0CR &= 0xFFFFFF00;
#if ENABLE_DEBUG
t1 = xtimer_now();
t1 = _xtimer_now();
#endif
AD0CR |= (1 << 24) | (1 << channel);
#if ENABLE_DEBUG
t2 = xtimer_now();
t2 = _xtimer_now();
#endif
while (1) {

View File

@ -21,8 +21,6 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
extern unsigned long xtimer_now(void);
/* --- MCI configurations --- */
#define N_BUF 4 /* Block transfer FIFO depth (>= 2) */
#define USE_4BIT 1 /* Use wide bus mode if SDC is detected */
@ -415,12 +413,12 @@ static int send_cmd(unsigned int idx, unsigned long arg, unsigned int rt, unsign
MCI_COMMAND = mc; /* Initiate command transaction */
//Timer[1] = 100;
uint32_t timerstart = xtimer_now();
uint32_t timerstart = xtimer_now_usec();
while (1) { /* Wait for end of the cmd/resp transaction */
//if (!Timer[1]) return 0;
if (xtimer_now() - timerstart > 10000) {
if ((xtimer_now_usec() - timerstart) > 10000) {
return 0;
}
@ -477,10 +475,10 @@ static int wait_ready(unsigned short tmr)
{
unsigned long rc;
uint32_t stoppoll = xtimer_now() + tmr * MS_IN_USEC;
uint32_t stoppoll = xtimer_now_usec() + tmr * MS_IN_USEC;
bool bBreak = false;
while (xtimer_now() < stoppoll/*Timer[0]*/) {
while (xtimer_now_usec() < stoppoll/*Timer[0]*/) {
if (send_cmd(CMD13, (unsigned long) CardRCA << 16, 1, &rc) && ((rc & 0x01E00) == 0x00800)) {
bBreak = true;
break;
@ -492,9 +490,6 @@ static int wait_ready(unsigned short tmr)
return bBreak;//Timer[0] ? 1 : 0;
}
/*-----------------------------------------------------------------------*/
/* Swap byte order */
/*-----------------------------------------------------------------------*/
@ -510,16 +505,12 @@ static void bswap_cp(unsigned char *dst, const unsigned long *src)
*dst++ = (unsigned char)(d >> 0);
}
/*--------------------------------------------------------------------------
Public Functions
---------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
/* Initialize Disk Drive */
/*-----------------------------------------------------------------------*/
@ -548,7 +539,7 @@ diskio_sta_t mci_initialize(void)
/*---- Card is 'idle' state ----*/
/* Initialization timeout of 1000 msec */
uint32_t start = xtimer_now();
uint32_t start = xtimer_now_usec();
/* SDC Ver2 */
if (send_cmd(CMD8, 0x1AA, 1, resp) && (resp[0] & 0xFFF) == 0x1AA) {
@ -558,7 +549,7 @@ diskio_sta_t mci_initialize(void)
do {
/* Wait while card is busy state (use ACMD41 with HCS bit) */
/* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */
if (xtimer_now() > start + 1000000/* !Timer[0] */) {
if (xtimer_now_usec() > (start + 1000000/* !Timer[0] */)) {
DEBUG("%s, %d: Timeout #1\n", RIOT_FILE_RELATIVE, __LINE__);
goto di_fail;
}
@ -584,8 +575,8 @@ diskio_sta_t mci_initialize(void)
DEBUG("%s, %d: %lX\n", RIOT_FILE_RELATIVE, __LINE__, resp[0]);
/* This loop will take a time. Insert wai_tsk(1) here for multitask envilonment. */
if (xtimer_now() > start + 1000000/* !Timer[0] */) {
DEBUG("now: %lu, started at: %lu\n", xtimer_now(), start);
if (xtimer_now_usec() > (start + 1000000/* !Timer[0] */)) {
DEBUG("now: %lu, started at: %lu\n", xtimer_now_usec(), start);
DEBUG("%s, %d: Timeout #2\n", RIOT_FILE_RELATIVE, __LINE__);
goto di_fail;
}

View File

@ -22,6 +22,7 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
#define AT30TSE75X_BUS_FREE_TIME_TICKS (xtimer_ticks_from_usec(AT30TSE75X_BUS_FREE_TIME_US))
static inline float temperature_to_float(uint16_t temp)
{
/* Integer part is 8-bit signed */
@ -37,7 +38,7 @@ static inline float temperature_to_float(uint16_t temp)
static int at30tse75x_get_register(at30tse75x_t* dev, uint8_t reg, uint16_t* data)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if (i2c_read_regs(dev->i2c, dev->addr, reg, data, 2) <= 0) {
DEBUG("[at30tse75x] Can't read register 0x%x\n", reg);
i2c_release(dev->i2c);
@ -51,7 +52,7 @@ static int at30tse75x_get_register(at30tse75x_t* dev, uint8_t reg, uint16_t* dat
static int at30tse75x_set_register(at30tse75x_t* dev, uint8_t reg, uint16_t* data)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if (i2c_write_regs(dev->i2c, dev->addr, reg, data, 2) <= 0) {
DEBUG("[at30tse75x] Can't write to register 0x%x\n", reg);
i2c_release(dev->i2c);
@ -65,8 +66,8 @@ static int at30tse75x_set_register(at30tse75x_t* dev, uint8_t reg, uint16_t* dat
static int at30tse75x_reset(at30tse75x_t* dev)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
if(i2c_write_byte(dev->i2c, 0x00, AT30TSE75X_CMD__GENERAL_CALL_RESET) != 1) {
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if (i2c_write_byte(dev->i2c, 0x00, AT30TSE75X_CMD__GENERAL_CALL_RESET) != 1) {
i2c_release(dev->i2c);
return -1;
}
@ -79,7 +80,7 @@ static int at30tse75x_reset(at30tse75x_t* dev)
int at30tse75x_get_config(at30tse75x_t* dev, uint8_t* data)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if (i2c_read_reg(dev->i2c, dev->addr, AT30TSE75X_REG__CONFIG, data) <= 0) {
DEBUG("[at30tse75x] Can't read CONFIG register\n");
i2c_release(dev->i2c);
@ -93,7 +94,7 @@ int at30tse75x_get_config(at30tse75x_t* dev, uint8_t* data)
int at30tse75x_set_config(at30tse75x_t* dev, uint8_t data)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if (i2c_write_reg(dev->i2c, dev->addr, AT30TSE75X_REG__CONFIG, data) <= 0) {
DEBUG("[at30tse75x] Can't write to CONFIG register\n");
i2c_release(dev->i2c);
@ -220,7 +221,7 @@ int at30tse75x_set_limit_high(at30tse75x_t* dev, int8_t t_high)
int at30tse75x_save_config(at30tse75x_t* dev)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if(i2c_write_byte(dev->i2c, dev->addr, AT30TSE75X_CMD__SAVE_TO_NVRAM) != 1) {
i2c_release(dev->i2c);
return -1;
@ -234,7 +235,7 @@ int at30tse75x_save_config(at30tse75x_t* dev)
int at30tse75x_restore_config(at30tse75x_t* dev)
{
i2c_acquire(dev->i2c);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_US);
xtimer_spin(AT30TSE75X_BUS_FREE_TIME_TICKS);
if(i2c_write_byte(dev->i2c, dev->addr, AT30TSE75X_CMD__RESTORE_FROM_NVRAM) != 1) {
i2c_release(dev->i2c);
return -1;

View File

@ -54,9 +54,9 @@ static uint16_t read(gpio_t pin, int bits)
/* measure the length between the next rising and falling flanks (the
* time the pin is high - smoke up :-) */
while (!gpio_read(pin));
start = xtimer_now();
start = xtimer_now_usec();
while (gpio_read(pin));
end = xtimer_now();
end = xtimer_now_usec();
/* if the high phase was more than 40us, we got a 1 */
if ((end - start) > PULSE_WIDTH_THRESHOLD) {
res |= 0x0001;

View File

@ -40,7 +40,7 @@ static uint32_t last = 0;
static int check_and_read(void *dev, phydat_t *res, int16_t *val, uint8_t unit)
{
dht_t *d = (dht_t *)dev;
uint32_t now = xtimer_now();
uint32_t now = xtimer_now_usec();
if ((now - last) > DHT_SAUL_HOLD_TIME) {
dht_read(d, &temp, &hum);

View File

@ -86,7 +86,7 @@ void ltc4150_start(void)
{
ltc4150_disable_int();
int_count = 0;
uint32_t now = xtimer_now();
uint32_t now = xtimer_now_usec();
ltc4150_sync_blocking();
start_time = now;
last_int_time = now;
@ -100,7 +100,7 @@ void ltc4150_stop(void)
void __attribute__((__no_instrument_function__)) ltc4150_interrupt(void)
{
uint32_t now = xtimer_now();
uint32_t now = xtimer_now_usec();
if (now >= last_int_time) {
last_int_duration = now - last_int_time;

View File

@ -33,8 +33,8 @@ extern "C" {
#endif
#define INITIAL_RX_POWER_0dB 0
#define DELAY_CS_TOGGLE_TICKS 2
#define DELAY_AFTER_FUNC_TICKS 2
#define DELAY_CS_TOGGLE_US 2
#define DELAY_AFTER_FUNC_US 2
#define DELAY_CE_HIGH_US (20)
#define DELAY_CHANGE_PWR_MODE_US (1500)
#define DELAY_CHANGE_TXRX_US (130)

View File

@ -27,6 +27,9 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
#define DELAY_CS_TOGGLE_TICKS (xtimer_ticks_from_usec(DELAY_CS_TOGGLE_US))
#define DELAY_AFTER_FUNC_TICKS (xtimer_ticks_from_usec(DELAY_AFTER_FUNC_US))
#define DELAY_CHANGE_TXRX_TICKS (xtimer_ticks_from_usec(DELAY_CHANGE_TXRX_US))
int nrf24l01p_read_reg(nrf24l01p_t *dev, char reg, char *answer)
{
@ -229,7 +232,7 @@ void nrf24l01p_transmit(nrf24l01p_t *dev)
xtimer_usleep(DELAY_CE_HIGH_US); /* at least 10 us high */
gpio_clear(dev->ce);
xtimer_spin(DELAY_CHANGE_TXRX_US);
xtimer_spin(DELAY_CHANGE_TXRX_TICKS);
}
int nrf24l01p_read_payload(nrf24l01p_t *dev, char *answer, unsigned int size)

View File

@ -40,7 +40,7 @@ typedef enum {
/** @brief Delay to wait between toggling CS pin, on most chips this can probably be
* removed. */
#define NVRAM_SPI_CS_TOGGLE_TICKS 1
#define NVRAM_SPI_CS_TOGGLE_TICKS xtimer_ticks_from_usec(1)
/**
* @brief Copy data from system memory to NVRAM.

View File

@ -138,7 +138,7 @@ static void _api_at_cmd(xbee_t *dev, uint8_t *cmd, uint8_t size, resp_t *resp)
/* start send data */
uart_write(dev->uart, dev->tx_buf, size + 6);
uint64_t sent_time = xtimer_now64();
xtimer_ticks64_t sent_time = xtimer_now64();
xtimer_t resp_timer;
@ -149,7 +149,9 @@ static void _api_at_cmd(xbee_t *dev, uint8_t *cmd, uint8_t size, resp_t *resp)
/* wait for results */
while ((dev->resp_limit != dev->resp_count) &&
(xtimer_now64() - sent_time < RESP_TIMEOUT_USEC)) {
(xtimer_less(
xtimer_diff32_64(xtimer_now64(), sent_time),
xtimer_ticks_from_usec(RESP_TIMEOUT_USEC)))) {
mutex_lock(&(dev->resp_lock));
}

View File

@ -27,11 +27,11 @@
int main(void)
{
uint32_t last_wakeup = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
while(1) {
xtimer_periodic_wakeup(&last_wakeup, INTERVAL);
printf("slept until %" PRIu32 "\n", xtimer_now());
printf("slept until %" PRIu32 "\n", xtimer_usec_from_ticks(xtimer_now()));
}
return 0;

View File

@ -196,12 +196,12 @@ void hal_watchdogStop(void)
clock_time_t hal_getTick(void)
{
return (clock_time_t)xtimer_now();
return (clock_time_t)xtimer_now_usec();
}
clock_time_t hal_getSec(void)
{
return (clock_time_t)xtimer_now() / SEC_IN_USEC;
return (clock_time_t)xtimer_now_usec() / SEC_IN_USEC;
}

View File

@ -81,9 +81,9 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t count)
LWIP_ASSERT("invalid semaphor", sys_sem_valid(sem));
if (count != 0) {
uint64_t stop, start;
start = xtimer_now64();
start = xtimer_now_usec64();
int res = sema_wait_timed((sema_t *)sem, count * MS_IN_USEC);
stop = xtimer_now64() - start;
stop = xtimer_now_usec64() - start;
if (res == -ETIMEDOUT) {
return SYS_ARCH_TIMEOUT;
}
@ -140,13 +140,13 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
xtimer_t timer = { .callback = _mbox_timeout, .arg = &mbox->mbox };
uint64_t start, stop;
start = xtimer_now64();
start = xtimer_now_usec64();
if (timeout > 0) {
uint64_t u_timeout = (timeout * MS_IN_USEC);
_xtimer_set64(&timer, (uint32_t)u_timeout, (uint32_t)(u_timeout >> 32));
}
mbox_get(&mbox->mbox, &m);
stop = xtimer_now64();
stop = xtimer_now_usec64();
xtimer_remove(&timer); /* in case timer did not time out */
switch (m.type) {
case _MSG_SUCCESS:

1
sys/div/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

46
sys/div/div.c Normal file
View File

@ -0,0 +1,46 @@
/**
* Copyright (C) 2016 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
* @ingroup sys_util
* @{
* @file
* @brief Integer division function implementations
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*
* @}
*/
#include <stdint.h>
#include <stdio.h>
#include "div.h"
uint64_t _div_mulhi64(const uint64_t a, const uint64_t b)
{
/* Handle overflow explicit because we don't have 128 bit integers on
* our platforms. */
const uint32_t a_lo = (const uint32_t)a;
const uint32_t a_hi = (const uint32_t)(a >> 32);
const uint32_t b_lo = (const uint32_t)b;
const uint32_t b_hi = (const uint32_t)(b >> 32);
const uint64_t a_x_b_mid = (const uint64_t)a_hi * b_lo;
const uint64_t b_x_a_mid = (const uint64_t)b_hi * a_lo;
const uint64_t a_x_b_lo = (const uint64_t)a_lo * b_lo;
const uint64_t a_x_b_hi = (const uint64_t)a_hi * b_hi;
/* We may get up to 2 carry bits from the lower part of the multiplication */
const uint32_t carry_bits = ((uint64_t)(uint32_t)a_x_b_mid +
(uint64_t)(uint32_t)b_x_a_mid +
(a_x_b_lo >> 32) ) >> 32;
const uint64_t multhi = a_x_b_hi +
(a_x_b_mid >> 32) + (b_x_a_mid >> 32) +
carry_bits;
return multhi;
}

View File

@ -1,5 +1,6 @@
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
* Copyright (C) 2016 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -7,14 +8,15 @@
*/
/**
* @brief Provides integer division functions
* @brief Integer division functions
*
* This header provides some integer division functions that can be used
* to prevent linking in compiler-generated ones, which are often larger.
*
* @file
* @ingroup sys_util
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Kaspar Schleiser <kaspar@schleiser.de>
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
* @{
*/
@ -29,35 +31,58 @@ extern "C" {
#endif
/**
* @brief Integer divide val by 15625
* @brief Approximation of (2**l)/d for d=15625, l=12, 32 bits
*/
#define DIV_H_INV_15625_32 0x431bde83ul
/**
* @brief Approximation of (2**l)/d for d=15625, l=12, 64 bits
*/
#define DIV_H_INV_15625_64 0x431bde82d7b634dbull
/**
* @brief Required shifts for division by 15625, l above
*/
#define DIV_H_INV_15625_SHIFT 12
/**
* @internal
* @brief Multiply two 64 bit integers into a 128 bit integer and return the upper half.
*
* @pre val <= 16383999997
* The implementation only uses 64 bit integers internally, no __int128 support
* is necessary.
*
* @see http://stackoverflow.com/questions/28868367/getting-the-high-part-of-64-bit-integer-multiplication
* @param[in] a operand a
* @param[in] b operand b
* @return (((uint128_t)a * b) >> 64)
*/
uint64_t _div_mulhi64(const uint64_t a, const uint64_t b);
/**
* @brief Integer divide val by 15625, 64 bit version
*
* @param[in] val dividend
* @return (val / 15625)
*/
static inline uint64_t div_u64_by_15625(uint64_t val)
{
/* a higher value would overflow 2^64 in the multiplication that follows */
assert(val <= 16383999997LLU);
return (val * 0x431bde83UL) >> (12 + 32);
if (val > 16383999997ull) {
return (_div_mulhi64(DIV_H_INV_15625_64, val) >> DIV_H_INV_15625_SHIFT);
}
return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32);
}
/**
* @brief Integer divide val by 1000000
*
* @pre val <= 1048575999808
*
* @param[in] val dividend
* @return (val / 1000000)
*/
static inline uint64_t div_u64_by_1000000(uint64_t val)
{
/* a higher value would overflow 2^64 in the multiplication that follows */
assert(val <= 1048575999808LLU);
return div_u64_by_15625(val>>6);
return div_u64_by_15625(val) >> 6;
}
/**
@ -66,15 +91,40 @@ static inline uint64_t div_u64_by_1000000(uint64_t val)
* This is used to quantize a 1MHz value to the closest 32768Hz value,
* e.g., for timers.
*
* The algorithm actually multiplies by 512 first, then divides by 15625,
* keeping the result closer to a floored floating point division.
* The algorithm uses the modular multiplicative inverse of 15625 to use only
* multiplication and bit shifts to perform the division.
*
* The result will be equal to the mathematical expression: floor((val * 512) / 15625)
*
* @param[in] val dividend
* @return (val / (15625/512))
*/
static inline uint32_t div_u32_by_15625div512(uint32_t val)
{
return ((uint64_t)(val) * 0x431bde83ul) >> (12 + 32 - 9);
return ((uint64_t)(val) * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
}
/**
* @brief Divide val by (15625/512)
*
* This is used to quantize a 1MHz value to the closest 32768Hz value,
* e.g., for timers.
*
* @param[in] val dividend
* @return (val / (15625/512))
*/
static inline uint64_t div_u64_by_15625div512(uint64_t val)
{
/*
* This saves around 1400 bytes of ROM on Cortex-M platforms (both ARMv6 and
* ARMv7) from avoiding linking against __aeabi_uldivmod and related helpers
*/
if (val > 16383999997ull) {
/* this would overflow 2^64 in the multiplication that follows, need to
* use the long version */
return (_div_mulhi64(DIV_H_INV_15625_64, val) >> (DIV_H_INV_15625_SHIFT - 9));
}
return (val * DIV_H_INV_15625_32) >> (DIV_H_INV_15625_SHIFT + 32 - 9);
}
/**

View File

@ -39,7 +39,7 @@
* (void)vector;
* (void)count;
*
* sum += (xtimer_now() - last_start);
* sum += (xtimer_now_usec() - last_start);
* mutex_unlock(&wait);
* }
*
@ -52,7 +52,7 @@
* // ...
* mutex_lock(&wait);
* for (int i = 0; i < PKT_NUMBER; i++) {
* last_start = xtimer_now();
* last_start = xtimer_now_usec();
* conn_udp_sendto("abcd", sizeof("abcd"), NULL, 0, &dst, sizeof(dst),
* AF_INET6, 0xcafe, 0xcafe);
* mutex_lock(&wait);

View File

@ -40,6 +40,24 @@
extern "C" {
#endif
/**
* @brief xtimer timestamp (64 bit)
*
* @note This is a struct in order to make the xtimer API type strict
*/
typedef struct {
uint64_t ticks64;
} xtimer_ticks64_t;
/**
* @brief xtimer timestamp (32 bit)
*
* @note This is a struct in order to make the xtimer API type strict
*/
typedef struct {
uint32_t ticks32;
} xtimer_ticks32_t;
/**
* @brief xtimer callback type
*/
@ -58,21 +76,21 @@ typedef struct xtimer {
} xtimer_t;
/**
* @brief get the current system time as 32bit microsecond value
* @brief get the current system time as 32bit time stamp value
*
* @note Overflows every ~71minutes, thus returns xtimer_now64() % 32,
* but is more efficient.
* @note Overflows 2**32 ticks, thus returns xtimer_now64() % 32,
* but is cheaper.
*
* @return current time as 32bit microsecond value
* @return current time as 32bit time stamp
*/
static inline uint32_t xtimer_now(void);
static inline xtimer_ticks32_t xtimer_now(void);
/**
* @brief get the current system time as 64bit microsecond value
* @brief get the current system time as 64bit time stamp
*
* @return current time as 64bit microsecond value
* @return current time as 64bit time stamp
*/
uint64_t xtimer_now64(void);
static inline xtimer_ticks64_t xtimer_now64(void);
/**
* @brief get the current system time into a timex_t
@ -81,6 +99,20 @@ uint64_t xtimer_now64(void);
*/
void xtimer_now_timex(timex_t *out);
/**
* @brief get the current system time in microseconds since start
*
* This is a convenience function for @c xtimer_usec_from_ticks(xtimer_now())
*/
static inline uint32_t xtimer_now_usec(void);
/**
* @brief get the current system time in microseconds since start
*
* This is a convenience function for @c xtimer_usec_from_ticks64(xtimer_now64())
*/
static inline uint64_t xtimer_now_usec64(void);
/**
* @brief xtimer initialization function
*
@ -98,7 +130,7 @@ void xtimer_init(void);
*
* @param[in] seconds the amount of seconds the thread should sleep
*/
static void xtimer_sleep(uint32_t seconds);
static inline void xtimer_sleep(uint32_t seconds);
/**
* @brief Pause the execution of a thread for some microseconds
@ -109,18 +141,7 @@ static void xtimer_sleep(uint32_t seconds);
*
* @param[in] microseconds the amount of microseconds the thread should sleep
*/
static void xtimer_usleep(uint32_t microseconds);
/**
* @brief Stop execution of a thread for some time, 64bit version
*
* When called from an ISR, this function will spin and thus block the MCU for
* the specified amount in microseconds, so only use it there for *very* short
* periods, e.g., less then XTIMER_BACKOFF.
*
* @param[in] microseconds the amount of microseconds the thread should sleep
*/
static inline void xtimer_usleep64(uint64_t microseconds);
static inline void xtimer_usleep(uint32_t microseconds);
/**
* @brief Stop execution of a thread for some time
@ -133,16 +154,38 @@ static inline void xtimer_usleep64(uint64_t microseconds);
*
* @param[in] nanoseconds the amount of nanoseconds the thread should sleep
*/
static void xtimer_nanosleep(uint32_t nanoseconds);
static inline void xtimer_nanosleep(uint32_t nanoseconds);
/**
* @brief Stop execution of a thread for some time, 32bit version
*
* When called from an ISR, this function will spin and thus block the MCU for
* the specified amount, so only use it there for *very* short periods,
* e.g. less than XTIMER_BACKOFF.
*
* @param[in] ticks number of ticks the thread should sleep
*/
static inline void xtimer_tsleep32(xtimer_ticks32_t ticks);
/**
* @brief Stop execution of a thread for some time, 64bit version
*
* When called from an ISR, this function will spin and thus block the MCU for
* the specified amount, so only use it there for *very* short periods,
* e.g. less than XTIMER_BACKOFF.
*
* @param[in] ticks number of ticks the thread should sleep
*/
static inline void xtimer_tsleep64(xtimer_ticks64_t ticks);
/**
* @brief Stop execution of a thread for some time, blocking
*
* This function will spin-block, so only use it *very* short periods.
*
* @param[in] microseconds the amount of microseconds the thread should spin
* @param[in] ticks the number of xtimer ticks the thread should spin for
*/
static inline void xtimer_spin(uint32_t microseconds);
static inline void xtimer_spin(xtimer_ticks32_t ticks);
/**
* @brief will cause the calling thread to be suspended until the absolute
@ -161,12 +204,12 @@ static inline void xtimer_spin(uint32_t microseconds);
* @param[in] last_wakeup base time stamp for the wakeup
* @param[in] period time in microseconds that will be added to last_wakeup
*/
void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period);
static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup, uint32_t period);
/**
* @brief Set a timer that sends a message
*
* This function sets a timer that will send a message @p offset microseconds
* This function sets a timer that will send a message @p offset ticks
* from now.
*
* The mesage struct specified by msg parameter will not be copied, e.g., it
@ -179,7 +222,7 @@ void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period);
* @param[in] msg ptr to msg that will be sent
* @param[in] target_pid pid the message will be sent to
*/
void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid);
static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid);
/**
* @brief Set a timer that sends a message, 64bit version
@ -197,7 +240,7 @@ void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t t
* @param[in] msg ptr to msg that will be sent
* @param[in] target_pid pid the message will be sent to
*/
void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid);
static inline void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid);
/**
* @brief Set a timer that wakes up a thread
@ -211,7 +254,7 @@ void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t
* @param[in] offset microseconds from now
* @param[in] pid pid of the thread that will be woken up
*/
void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid);
static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid);
/**
* @brief Set a timer that wakes up a thread, 64bit version
@ -225,7 +268,7 @@ void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid);
* @param[in] offset microseconds from now
* @param[in] pid pid of the thread that will be woken up
*/
void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid);
static inline void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid);
/**
* @brief Set a timer to execute a callback at some time in the future
@ -233,7 +276,7 @@ void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid);
* Expects timer->callback to be set.
*
* The callback specified in the timer struct will be executed @p offset
* microseconds in the future.
* ticks in the future.
*
* @warning BEWARE! Callbacks from xtimer_set() are being executed in interrupt
* context (unless offset < XTIMER_BACKOFF). DON'T USE THIS FUNCTION unless you
@ -245,7 +288,7 @@ void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid);
* @param[in] offset time in microseconds from now specifying that timer's
* callback's execution time
*/
void xtimer_set(xtimer_t *timer, uint32_t offset);
static inline void xtimer_set(xtimer_t *timer, uint32_t offset);
/**
* @brief remove a timer
@ -259,24 +302,128 @@ void xtimer_remove(xtimer_t *timer);
/**
* @brief receive a message blocking but with timeout
*
* @param[out] msg pointer to a msg_t which will be filled in case of
* @param[out] msg pointer to a msg_t which will be filled in case of
* no timeout
* @param[in] us timeout in microseconds relative
* @param[in] timeout timeout in microseconds relative
*
* @return < 0 on error, other value otherwise
* @return < 0 on error, other value otherwise
*/
int xtimer_msg_receive_timeout(msg_t *msg, uint32_t us);
static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout);
/**
* @brief receive a message blocking but with timeout, 64bit version
*
* @param[out] msg pointer to a msg_t which will be filled in case of no
* @param[out] msg pointer to a msg_t which will be filled in case of no
* timeout
* @param[in] us timeout in microseconds relative
* @param[in] timeout timeout in microseconds relative
*
* @return < 0 on error, other value otherwise
* @return < 0 on error, other value otherwise
*/
int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
static inline int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout);
/**
* @brief Convert microseconds to xtimer ticks
*
* @param[in] usec microseconds
*
* @return xtimer time stamp
*/
static inline xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec);
/**
* @brief Convert microseconds to xtimer ticks, 64 bit version
*
* @param[in] usec microseconds
*
* @return xtimer time stamp
*/
static inline xtimer_ticks64_t xtimer_ticks_from_usec64(uint64_t usec);
/**
* @brief Convert xtimer ticks to microseconds
*
* @param[in] ticks xtimer time stamp
*
* @return microseconds
*/
static inline uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks);
/**
* @brief Convert xtimer ticks to microseconds, 64 bit version
*
* @param[in] ticks xtimer time stamp
*
* @return microseconds
*/
static inline uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks);
/**
* @brief Create an xtimer time stamp
*
* @param[in] ticks number of xtimer ticks
*
* @return xtimer time stamp
*/
static inline xtimer_ticks32_t xtimer_ticks(uint32_t ticks);
/**
* @brief Create an xtimer time stamp, 64 bit version
*
* @param[in] ticks number of xtimer ticks
*
* @return xtimer time stamp
*/
static inline xtimer_ticks64_t xtimer_ticks64(uint64_t ticks);
/**
* @brief Compute difference between two xtimer time stamps
*
* @param[in] a left operand
* @param[in] b right operand
*
* @return @p a - @p b
*/
static inline xtimer_ticks32_t xtimer_diff(xtimer_ticks32_t a, xtimer_ticks32_t b);
/**
* @brief Compute difference between two xtimer time stamps, 64 bit version
*
* @param[in] a left operand
* @param[in] b right operand
*
* @return @p a - @p b
*/
static inline xtimer_ticks64_t xtimer_diff64(xtimer_ticks64_t a, xtimer_ticks64_t b);
/**
* @brief Compute 32 bit difference between two 64 bit xtimer time stamps
*
* @param[in] a left operand
* @param[in] b right operand
*
* @return @p a - @p b cast truncated to 32 bit
*/
static inline xtimer_ticks32_t xtimer_diff32_64(xtimer_ticks64_t a, xtimer_ticks64_t b);
/**
* @brief Compare two xtimer time stamps
*
* @param[in] a left operand
* @param[in] b right operand
*
* @return @p a < @p b
*/
static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b);
/**
* @brief Compare two xtimer time stamps, 64 bit version
*
* @param[in] a left operand
* @param[in] b right operand
*
* @return @p a < @p b
*/
static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b);
/**
* @brief xtimer backoff value
@ -291,7 +438,7 @@ int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
#endif
/**
* @brief xtimer overhead value
* @brief xtimer overhead value, in hardware ticks
*
* This value specifies the time a timer will be late if uncorrected, e.g.,
* the system-specific xtimer execution time from timer ISR to executing
@ -315,9 +462,9 @@ int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
#ifndef XTIMER_ISR_BACKOFF
/**
* @brief xtimer isr backoff time
* @brief xtimer IRQ backoff time, in hardware ticks
*
* When scheduling the next isr, if it is less than the backoff time
* When scheduling the next IRQ, if it is less than the backoff time
* in the future, just spin.
*
* This is supposed to be defined per-device in e.g., periph_conf.h.
@ -352,14 +499,16 @@ int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
/**
* @brief xtimer prescaler value
*
* xtimer assumes it is running with an underlying 1MHz timer.
* If the timer is slower by a power of two, XTIMER_SHIFT can be used to
* adjust the difference.
* If the underlying hardware timer is running at a power of two multiple of
* 15625, XTIMER_SHIFT can be used to adjust the difference.
*
* This will also initialize the underlying periph timer with
* us_per_tick == (1<<XTIMER_SHIFT).
* For a 1 MHz hardware timer, set XTIMER_SHIFT to 0.
*
* For example, if the timer is running with 250khz, set XTIMER_SHIFT to 2.
* For a 4 MHz hardware timer, set XTIMER_SHIFT to 2.
* For a 16 MHz hardware timer, set XTIMER_SHIFT to 4.
* For a 250 kHz hardware timer, set XTIMER_SHIFT to 2.
*
* The direction of the shift is handled by the macros in tick_conversion.h
*/
#define XTIMER_SHIFT (0)
#endif
@ -395,6 +544,7 @@ int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
#define XTIMER_WIDTH (32)
#endif
#if (XTIMER_WIDTH != 32) || DOXYGEN
/**
* @brief xtimer timer mask
*
@ -404,13 +554,19 @@ int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t us);
* For a 16bit timer, the mask would be 0xFFFF0000, for a 24bit timer, the mask
* would be 0xFF000000.
*/
#if XTIMER_WIDTH != 32
#define XTIMER_MASK ((0xffffffff >> XTIMER_WIDTH) << XTIMER_WIDTH)
#else
#define XTIMER_MASK (0)
#endif
#define XTIMER_MASK_SHIFTED XTIMER_TICKS_TO_USEC(XTIMER_MASK)
#ifndef XTIMER_HZ
/**
* @brief Frequency of the underlying hardware timer
*/
#define XTIMER_HZ 1000000ul
#endif
#include "xtimer/tick_conversion.h"
#include "xtimer/implementation.h"

View File

@ -33,14 +33,6 @@ extern "C" {
extern volatile uint32_t _xtimer_high_cnt;
#endif
#if (XTIMER_SHIFT < 0)
#define XTIMER_USEC_TO_TICKS(value) ( (value) << -XTIMER_SHIFT )
#define XTIMER_TICKS_TO_USEC(value) ( (value) >> -XTIMER_SHIFT )
#else
#define XTIMER_USEC_TO_TICKS(value) ( (value) >> XTIMER_SHIFT )
#define XTIMER_TICKS_TO_USEC(value) ( (value) << XTIMER_SHIFT )
#endif
/**
* @brief IPC message type for xtimer msg callback
*/
@ -51,11 +43,7 @@ extern volatile uint32_t _xtimer_high_cnt;
*/
static inline uint32_t _xtimer_lltimer_now(void)
{
#if XTIMER_SHIFT
return XTIMER_TICKS_TO_USEC((uint32_t)timer_read(XTIMER_DEV));
#else
return timer_read(XTIMER_DEV);
#endif
}
/**
@ -63,7 +51,7 @@ static inline uint32_t _xtimer_lltimer_now(void)
*/
static inline uint32_t _xtimer_lltimer_mask(uint32_t val)
{
return val & ~XTIMER_MASK_SHIFTED;
return val & ~XTIMER_MASK;
}
/**
@ -71,22 +59,36 @@ static inline uint32_t _xtimer_lltimer_mask(uint32_t val)
* @brief xtimer internal stuff
* @internal
*/
uint64_t _xtimer_now64(void);
int _xtimer_set_absolute(xtimer_t *timer, uint32_t target);
void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset);
void _xtimer_sleep(uint32_t offset, uint32_t long_offset);
void _xtimer_set(xtimer_t *timer, uint32_t offset);
void _xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period);
void _xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid);
void _xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid);
void _xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid);
void _xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid);
void _xtimer_set(xtimer_t *timer, uint32_t offset);
int _xtimer_msg_receive_timeout(msg_t *msg, uint32_t ticks);
int _xtimer_msg_receive_timeout64(msg_t *msg, uint64_t ticks);
/**
* @brief Sleep for the given number of ticks
*/
void _xtimer_tsleep(uint32_t offset, uint32_t long_offset);
/** @} */
#ifndef XTIMER_MIN_SPIN
/**
* @brief Minimal value xtimer_spin() can spin
*/
#define XTIMER_MIN_SPIN XTIMER_TICKS_TO_USEC(1)
#define XTIMER_MIN_SPIN _xtimer_usec_from_ticks(1)
#endif
#ifndef DOXYGEN
/* Doxygen warns that these are undocumented, but the documentation can be found in xtimer.h */
static inline uint32_t xtimer_now(void)
static inline uint32_t _xtimer_now(void)
{
#if XTIMER_MASK
uint32_t latched_high_cnt, now;
@ -106,7 +108,31 @@ static inline uint32_t xtimer_now(void)
#endif
}
static inline void xtimer_spin(uint32_t offset) {
static inline xtimer_ticks32_t xtimer_now(void)
{
xtimer_ticks32_t ret;
ret.ticks32 = _xtimer_now();
return ret;
}
static inline xtimer_ticks64_t xtimer_now64(void)
{
xtimer_ticks64_t ret;
ret.ticks64 = _xtimer_now64();
return ret;
}
static inline uint32_t xtimer_now_usec(void)
{
return xtimer_usec_from_ticks(xtimer_now());
}
static inline uint64_t xtimer_now_usec64(void)
{
return xtimer_usec_from_ticks64(xtimer_now64());
}
static inline void _xtimer_spin(uint32_t offset) {
uint32_t start = _xtimer_lltimer_now();
#if XTIMER_MASK
offset = _xtimer_lltimer_mask(offset);
@ -116,24 +142,158 @@ static inline void xtimer_spin(uint32_t offset) {
#endif
}
static inline void _xtimer_tsleep32(uint32_t ticks)
{
_xtimer_tsleep(ticks, 0);
}
static inline void _xtimer_tsleep64(uint64_t ticks)
{
_xtimer_tsleep((uint32_t)ticks, (uint32_t)(ticks >> 32));
}
static inline void xtimer_spin(xtimer_ticks32_t ticks) {
_xtimer_spin(ticks.ticks32);
}
static inline void xtimer_usleep(uint32_t microseconds)
{
_xtimer_sleep(microseconds, 0);
_xtimer_tsleep32(_xtimer_ticks_from_usec(microseconds));
}
static inline void xtimer_usleep64(uint64_t microseconds)
{
_xtimer_sleep((uint32_t) microseconds, (uint32_t) (microseconds >> 32));
_xtimer_tsleep64(_xtimer_ticks_from_usec64(microseconds));
}
static inline void xtimer_sleep(uint32_t seconds)
{
xtimer_usleep64((uint64_t)seconds * SEC_IN_USEC);
_xtimer_tsleep64(_xtimer_ticks_from_usec64((uint64_t)seconds * SEC_IN_USEC));
}
static inline void xtimer_nanosleep(uint32_t nanoseconds)
{
_xtimer_sleep(nanoseconds / USEC_IN_NS, 0);
_xtimer_tsleep32(_xtimer_ticks_from_usec(nanoseconds / USEC_IN_NS));
}
static inline void xtimer_tsleep32(xtimer_ticks32_t ticks)
{
_xtimer_tsleep32(ticks.ticks32);
}
static inline void xtimer_tsleep64(xtimer_ticks64_t ticks)
{
_xtimer_tsleep64(ticks.ticks64);
}
static inline void xtimer_periodic_wakeup(xtimer_ticks32_t *last_wakeup, uint32_t period)
{
_xtimer_periodic_wakeup(&last_wakeup->ticks32, _xtimer_ticks_from_usec(period));
}
static inline void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid)
{
_xtimer_set_msg(timer, _xtimer_ticks_from_usec(offset), msg, target_pid);
}
static inline void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid)
{
_xtimer_set_msg64(timer, _xtimer_ticks_from_usec64(offset), msg, target_pid);
}
static inline void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid)
{
_xtimer_set_wakeup(timer, _xtimer_ticks_from_usec(offset), pid);
}
static inline void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid)
{
_xtimer_set_wakeup64(timer, _xtimer_ticks_from_usec64(offset), pid);
}
static inline void xtimer_set(xtimer_t *timer, uint32_t offset)
{
_xtimer_set(timer, _xtimer_ticks_from_usec(offset));
}
static inline int xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout)
{
return _xtimer_msg_receive_timeout(msg, _xtimer_ticks_from_usec(timeout));
}
static inline int xtimer_msg_receive_timeout64(msg_t *msg, uint64_t timeout)
{
return _xtimer_msg_receive_timeout64(msg, _xtimer_ticks_from_usec64(timeout));
}
static inline xtimer_ticks32_t xtimer_ticks_from_usec(uint32_t usec)
{
xtimer_ticks32_t ticks;
ticks.ticks32 = _xtimer_ticks_from_usec(usec);
return ticks;
}
static inline xtimer_ticks64_t xtimer_ticks_from_usec64(uint64_t usec)
{
xtimer_ticks64_t ticks;
ticks.ticks64 = _xtimer_ticks_from_usec64(usec);
return ticks;
}
static inline uint32_t xtimer_usec_from_ticks(xtimer_ticks32_t ticks)
{
return _xtimer_usec_from_ticks(ticks.ticks32);
}
static inline uint64_t xtimer_usec_from_ticks64(xtimer_ticks64_t ticks)
{
return _xtimer_usec_from_ticks64(ticks.ticks64);
}
static inline xtimer_ticks32_t xtimer_ticks(uint32_t ticks)
{
xtimer_ticks32_t ret;
ret.ticks32 = ticks;
return ret;
}
static inline xtimer_ticks64_t xtimer_ticks64(uint64_t ticks)
{
xtimer_ticks64_t ret;
ret.ticks64 = ticks;
return ret;
}
static inline xtimer_ticks32_t xtimer_diff(xtimer_ticks32_t a, xtimer_ticks32_t b)
{
xtimer_ticks32_t ret;
ret.ticks32 = a.ticks32 - b.ticks32;
return ret;
}
static inline xtimer_ticks64_t xtimer_diff64(xtimer_ticks64_t a, xtimer_ticks64_t b)
{
xtimer_ticks64_t ret;
ret.ticks64 = a.ticks64 - b.ticks64;
return ret;
}
static inline xtimer_ticks32_t xtimer_diff32_64(xtimer_ticks64_t a, xtimer_ticks64_t b)
{
uint64_t diff = a.ticks64 - b.ticks64;
xtimer_ticks32_t ret;
ret.ticks32 = diff;
return ret;
}
static inline bool xtimer_less(xtimer_ticks32_t a, xtimer_ticks32_t b)
{
return (a.ticks32 < b.ticks32);
}
static inline bool xtimer_less64(xtimer_ticks64_t a, xtimer_ticks64_t b)
{
return (a.ticks64 < b.ticks64);
}
#endif /* !defined(DOXYGEN) */

View File

@ -0,0 +1,138 @@
/*
* Copyright (C) 2016 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup sys_xtimer
*
* @{
* @file
* @brief xtimer tick <-> seconds conversions for different values of XTIMER_HZ
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef XTIMER_TICK_CONVERSION_H
#define XTIMER_TICK_CONVERSION_H
#ifndef XTIMER_H
#error "Do not include this file directly! Use xtimer.h instead"
#endif
#include "div.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Some optimizations for common timer frequencies */
#if (XTIMER_SHIFT != 0)
#if (XTIMER_HZ % 15625 != 0)
#error XTIMER_HZ must be a multiple of 15625 (5^6) when using XTIMER_SHIFT
#endif
#if (XTIMER_HZ > 1000000ul)
#if (XTIMER_HZ != (1000000ul << XTIMER_SHIFT))
#error XTIMER_HZ != (1000000ul << XTIMER_SHIFT)
#endif
/* XTIMER_HZ is a power-of-two multiple of 1 MHz */
/* e.g. cc2538 uses a 16 MHz timer */
inline static uint32_t _xtimer_ticks_from_usec(uint32_t usec) {
return (usec << XTIMER_SHIFT); /* multiply by power of two */
}
inline static uint64_t _xtimer_ticks_from_usec64(uint64_t usec) {
return (usec << XTIMER_SHIFT); /* multiply by power of two */
}
inline static uint32_t _xtimer_usec_from_ticks(uint32_t ticks) {
return (ticks >> XTIMER_SHIFT); /* divide by power of two */
}
inline static uint64_t _xtimer_usec_from_ticks64(uint64_t ticks) {
return (ticks >> XTIMER_SHIFT); /* divide by power of two */
}
#else /* !(XTIMER_HZ > 1000000ul) */
#if ((XTIMER_HZ << XTIMER_SHIFT) != 1000000ul)
#error (XTIMER_HZ << XTIMER_SHIFT) != 1000000ul
#endif
/* 1 MHz is a power-of-two multiple of XTIMER_HZ */
/* e.g. ATmega2560 uses a 250 kHz timer */
inline static uint32_t _xtimer_ticks_from_usec(uint32_t usec) {
return (usec >> XTIMER_SHIFT); /* divide by power of two */
}
inline static uint64_t _xtimer_ticks_from_usec64(uint64_t usec) {
return (usec >> XTIMER_SHIFT); /* divide by power of two */
}
inline static uint32_t _xtimer_usec_from_ticks(uint32_t ticks) {
return (ticks << XTIMER_SHIFT); /* multiply by power of two */
}
inline static uint64_t _xtimer_usec_from_ticks64(uint64_t ticks) {
return (ticks << XTIMER_SHIFT); /* multiply by power of two */
}
#endif /* defined(XTIMER_SHIFT) && (XTIMER_SHIFT != 0) */
#elif XTIMER_HZ == (1000000ul)
/* This is the most straightforward as the xtimer API is based around
* microseconds for representing time values. */
inline static uint32_t _xtimer_usec_from_ticks(uint32_t ticks) {
return ticks; /* no-op */
}
inline static uint64_t _xtimer_usec_from_ticks64(uint64_t ticks) {
return ticks; /* no-op */
}
inline static uint32_t _xtimer_ticks_from_usec(uint32_t usec) {
return usec; /* no-op */
}
inline static uint64_t _xtimer_ticks_from_usec64(uint64_t usec) {
return usec; /* no-op */
}
#elif XTIMER_HZ == (32768ul)
/* This is a common frequency for RTC crystals. We use the fact that the
* greatest common divisor between 32768 and 1000000 is 64, so instead of
* multiplying by the fraction (32768 / 1000000), we will instead use
* (512 / 15625), which reduces the truncation caused by the integer widths */
inline static uint32_t _xtimer_ticks_from_usec(uint32_t usec) {
return div_u32_by_15625div512(usec);
}
inline static uint64_t _xtimer_ticks_from_usec64(uint64_t usec) {
return div_u64_by_15625div512(usec);
}
inline static uint32_t _xtimer_usec_from_ticks(uint32_t ticks) {
/* return (usec * 15625) / 512; */
/* Using 64 bit multiplication to avoid truncating the top 9 bits */
uint64_t usec = (uint64_t)ticks * 15625ul;
return (usec >> 9); /* equivalent to (usec / 512) */
}
inline static uint64_t _xtimer_usec_from_ticks64(uint64_t ticks) {
/* return (usec * 15625) / 512; */
uint64_t usec = (uint64_t)ticks * 15625ul;
return (usec >> 9); /* equivalent to (usec / 512) */
}
#else
/* No matching implementation found, try to give meaningful error messages */
#if ((XTIMER_HZ % 15625) == 0)
#error Unsupported hardware timer frequency (XTIMER_HZ), missing XTIMER_SHIFT in board.h? See xtimer.h documentation for more info
#else
#error Unknown hardware timer frequency (XTIMER_HZ), check board.h and/or add an implementation in sys/include/xtimer/tick_conversion.h
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@ -133,7 +133,7 @@ gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_update(uint8_t id, const ipv6_addr_t *p
static uint32_t _current_minute(void)
{
return xtimer_now() / (SEC_IN_USEC * 60);
return xtimer_now_usec() / (SEC_IN_USEC * 60);
}
static void _update_lifetime(uint8_t id)

View File

@ -250,7 +250,7 @@ static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size)
static void _rbuf_gc(void)
{
uint32_t now_usec = xtimer_now();
uint32_t now_usec = xtimer_now_usec();
unsigned int i;
for (i = 0; i < RBUF_SIZE; i++) {
@ -275,7 +275,7 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
size_t size, uint16_t tag)
{
rbuf_t *res = NULL, *oldest = NULL;
uint32_t now_usec = xtimer_now();
uint32_t now_usec = xtimer_now_usec();
for (unsigned int i = 0; i < RBUF_SIZE; i++) {
/* check first if entry already available */

View File

@ -252,7 +252,7 @@ static void *_event_loop(void *args)
void _update_lifetime(void)
{
uint32_t now = xtimer_now();
uint32_t now = xtimer_now_usec();
uint16_t now_sec = now / SEC_IN_USEC;
gnrc_rpl_parent_t *parent;

View File

@ -225,7 +225,7 @@ bool gnrc_rpl_parent_remove(gnrc_rpl_parent_t *parent)
/* set the default route to the next parent for now */
if (parent->next) {
uint32_t now = xtimer_now() / SEC_IN_USEC;
uint32_t now = xtimer_now_usec() / SEC_IN_USEC;
fib_add_entry(&gnrc_ipv6_fib_table,
dodag->iface,
(uint8_t *) ipv6_addr_unspecified.u8,
@ -266,7 +266,7 @@ void gnrc_rpl_parent_update(gnrc_rpl_dodag_t *dodag, gnrc_rpl_parent_t *parent)
{
/* update Parent lifetime */
if (parent != NULL) {
uint32_t now = xtimer_now();
uint32_t now = xtimer_now_usec();
parent->lifetime = (now / SEC_IN_USEC) + (dodag->default_lifetime * dodag->lifetime_unit);
#ifdef MODULE_GNRC_RPL_P2P
if (dodag->instance->mop != GNRC_RPL_P2P_MOP) {

View File

@ -158,7 +158,7 @@ int csma_sender_csma_ca_send(netdev2_t *dev, struct iovec *vector,
/* if we arrive here, then we must perform the CSMA/CA procedure
ourselves by software */
random_init(xtimer_now());
random_init(_xtimer_now());
DEBUG("csma: Starting software CSMA/CA....\n");
int nb = 0, be = conf->min_be;

View File

@ -28,6 +28,7 @@
#include "mutex.h"
#include "msg.h"
#include "xtimer.h"
#include "timex.h"
#include "utlist.h"
#define ENABLE_DEBUG (0)
@ -61,7 +62,7 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN];
*/
static void fib_lifetime_to_absolute(uint32_t ms, uint64_t *target)
{
*target = xtimer_now64() + (ms * 1000);
*target = xtimer_now_usec64() + (ms * MS_IN_USEC);
}
/**
@ -80,7 +81,7 @@ static void fib_lifetime_to_absolute(uint32_t ms, uint64_t *target)
*/
static int fib_find_entry(fib_table_t *table, uint8_t *dst, size_t dst_size,
fib_entry_t **entry_arr, size_t *entry_arr_size) {
uint64_t now = xtimer_now64();
uint64_t now = xtimer_now_usec64();
size_t count = 0;
size_t prefix_size = 0;
@ -703,7 +704,7 @@ int fib_sr_create(fib_table_t *table, fib_sr_t **fib_sr, kernel_pid_t sr_iface_i
*/
static int fib_sr_check_lifetime(fib_sr_t *fib_sr)
{
uint64_t tm = fib_sr->sr_lifetime - xtimer_now64();
uint64_t tm = fib_sr->sr_lifetime - xtimer_now_usec64();
/* check if the lifetime expired */
if ((int64_t)tm < 0) {
/* remove this sr if its lifetime expired */
@ -777,7 +778,7 @@ int fib_sr_read_head(fib_table_t *table, fib_sr_t *fib_sr, kernel_pid_t *iface_i
*iface_id = fib_sr->sr_iface_id;
*sr_flags = fib_sr->sr_flags;
*sr_lifetime = fib_sr->sr_lifetime - xtimer_now64();
*sr_lifetime = fib_sr->sr_lifetime - xtimer_now_usec64();
mutex_unlock(&(table->mtx_access));
return 0;
@ -1530,7 +1531,7 @@ static void fib_print_address(universal_address_container_t *entry)
void fib_print_routes(fib_table_t *table)
{
mutex_lock(&(table->mtx_access));
uint64_t now = xtimer_now64();
uint64_t now = xtimer_now_usec64();
if (table->table_type == FIB_TABLE_TYPE_SH) {
printf("%-" FIB_ADDR_PRINT_LENS "s %-17s %-" FIB_ADDR_PRINT_LENS "s %-10s %-16s"

View File

@ -340,7 +340,7 @@ int _gettimeofday_r(struct _reent *r, struct timeval *restrict tp, void *restric
{
(void)tzp;
(void) r;
uint64_t now = xtimer_now64();
uint64_t now = xtimer_now_usec64();
tp->tv_sec = div_u64_by_1000000(now);
tp->tv_usec = now - (tp->tv_sec * SEC_IN_USEC);
return 0;

View File

@ -33,16 +33,15 @@
int sem_timedwait(sem_t *sem, const struct timespec *abstime)
{
uint64_t now, timeout = (((uint64_t)abstime->tv_sec) * SEC_IN_USEC) +
uint64_t timeout = (((uint64_t)abstime->tv_sec) * SEC_IN_USEC) +
(abstime->tv_nsec / USEC_IN_NS);
int res;
now = xtimer_now64();
uint64_t now = xtimer_now_usec64();
if (now > timeout) {
errno = ETIMEDOUT;
return -1;
}
timeout = timeout - now;
res = sema_wait_timed((sema_t *)sem, timeout);
int res = sema_wait_timed((sema_t *)sem, timeout);
if (res < 0) {
errno = -res;
return -1;

View File

@ -313,7 +313,7 @@ int uart_stdio_read(char* buffer, int count) {
/* We only unlock when rtt_stdio_enable_stdin is called
Note that we assume only one caller invoked this function */
}
uint32_t last_wakeup = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
while(1) {
xtimer_periodic_wakeup(&last_wakeup, STDIO_POLL_INTERVAL);
res = rtt_read(buffer, count);
@ -326,7 +326,7 @@ int uart_stdio_read(char* buffer, int count) {
int uart_stdio_write(const char* buffer, int len) {
int written = rtt_write(buffer, len);
uint32_t last_wakeup = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
while (blocking_stdout && written < len) {
xtimer_periodic_wakeup(&last_wakeup, STDIO_POLL_INTERVAL);
written += rtt_write(&buffer[written], len-written);

View File

@ -260,7 +260,7 @@ int _gnrc_rpl_dodag_show(void)
gnrc_rpl_dodag_t *dodag = NULL;
char addr_str[IPV6_ADDR_MAX_STR_LEN];
int8_t cleanup;
uint64_t tc, ti, xnow = xtimer_now64();
uint64_t tc, ti, xnow = xtimer_now_usec64();
for (uint8_t i = 0; i < GNRC_RPL_INSTANCES_NUMOF; ++i) {
if (gnrc_rpl_instances[i].state == 0) {

View File

@ -233,7 +233,7 @@ int _icmpv6_ping(int argc, char **argv)
remaining = count;
ping_start = xtimer_now64();
ping_start = xtimer_now_usec64();
while ((remaining--) > 0) {
gnrc_pktsnip_t *pkt;
@ -269,7 +269,7 @@ int _icmpv6_ping(int argc, char **argv)
((gnrc_netif_hdr_t *)pkt->data)->if_pid = src_iface;
}
start = xtimer_now();
start = xtimer_now_usec();
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
puts("error: unable to send ICMPv6 echo request\n");
gnrc_pktbuf_release(pkt);
@ -281,7 +281,7 @@ int _icmpv6_ping(int argc, char **argv)
uint32_t stop;
switch (msg.type) {
case GNRC_NETAPI_MSG_TYPE_RCV:
stop = xtimer_now() - start;
stop = xtimer_now_usec() - start;
gnrc_pktsnip_t *pkt = msg.content.ptr;
success += _handle_reply(pkt, stop);
@ -321,7 +321,7 @@ int _icmpv6_ping(int argc, char **argv)
xtimer_usleep64(delay * MS_IN_USEC);
}
if ((++stat_counter == stat_interval) || (remaining == 0)) {
uint64_t total_time = xtimer_now64() - ping_start;
uint64_t total_time = xtimer_now_usec64() - ping_start;
_print_stats(addr_str, success, (count - remaining), total_time, sum_rtt, min_rtt,
max_rtt);
stat_counter = 0;

View File

@ -36,7 +36,7 @@ int _random_init(int argc, char **argv)
if (argc == 1) {
#ifdef MODULE_XTIMER
initval = xtimer_now();
initval = _xtimer_now();
printf("PRNG initialized to current time: %d\n", initval);
#else
(void)initval;

View File

@ -38,11 +38,11 @@ static void _callback_unlock_mutex(void* arg)
mutex_unlock(mutex);
}
void _xtimer_sleep(uint32_t offset, uint32_t long_offset)
void _xtimer_tsleep(uint32_t offset, uint32_t long_offset)
{
if (irq_is_in()) {
assert(!long_offset);
xtimer_spin(offset);
_xtimer_spin(offset);
return;
}
@ -58,7 +58,7 @@ void _xtimer_sleep(uint32_t offset, uint32_t long_offset)
mutex_lock(&mutex);
}
void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) {
void _xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) {
xtimer_t timer;
mutex_t mutex = MUTEX_INIT;
@ -66,7 +66,7 @@ void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) {
timer.arg = (void*) &mutex;
uint32_t target = (*last_wakeup) + period;
uint32_t now = xtimer_now();
uint32_t now = _xtimer_now();
/* make sure we're not setting a value in the past */
if (now < (*last_wakeup)) {
/* base timer overflowed between last_wakeup and now */
@ -103,7 +103,7 @@ void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) {
uint32_t offset = target - now;
DEBUG("xps, now: %9" PRIu32 ", tgt: %9" PRIu32 ", off: %9" PRIu32 "\n", now, target, offset);
if (offset < XTIMER_PERIODIC_SPIN) {
xtimer_spin(offset);
_xtimer_spin(offset);
}
else {
if (offset < XTIMER_PERIODIC_RELATIVE) {
@ -112,14 +112,13 @@ void xtimer_periodic_wakeup(uint32_t *last_wakeup, uint32_t period) {
*
* Since interrupts are normally enabled inside this function, this time may
* be undeterministic. */
target = xtimer_now() + offset;
target = _xtimer_now() + offset;
}
mutex_lock(&mutex);
DEBUG("xps, abs: %" PRIu32 "\n", target);
_xtimer_set_absolute(&timer, target);
mutex_lock(&mutex);
}
out:
*last_wakeup = target;
}
@ -139,13 +138,13 @@ static inline void _setup_msg(xtimer_t *timer, msg_t *msg, kernel_pid_t target_p
msg->sender_pid = target_pid;
}
void xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid)
void _xtimer_set_msg(xtimer_t *timer, uint32_t offset, msg_t *msg, kernel_pid_t target_pid)
{
_setup_msg(timer, msg, target_pid);
xtimer_set(timer, offset);
_xtimer_set(timer, offset);
}
void xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid)
void _xtimer_set_msg64(xtimer_t *timer, uint64_t offset, msg_t *msg, kernel_pid_t target_pid)
{
_setup_msg(timer, msg, target_pid);
_xtimer_set64(timer, offset, offset >> 32);
@ -156,15 +155,15 @@ static void _callback_wakeup(void* arg)
thread_wakeup((kernel_pid_t)((intptr_t)arg));
}
void xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid)
void _xtimer_set_wakeup(xtimer_t *timer, uint32_t offset, kernel_pid_t pid)
{
timer->callback = _callback_wakeup;
timer->arg = (void*) ((intptr_t)pid);
xtimer_set(timer, offset);
_xtimer_set(timer, offset);
}
void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid)
void _xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid)
{
timer->callback = _callback_wakeup;
timer->arg = (void*) ((intptr_t)pid);
@ -174,7 +173,7 @@ void xtimer_set_wakeup64(xtimer_t *timer, uint64_t offset, kernel_pid_t pid)
void xtimer_now_timex(timex_t *out)
{
uint64_t now = xtimer_now64();
uint64_t now = xtimer_usec_from_ticks64(xtimer_now64());
out->seconds = div_u64_by_1000000(now);
out->microseconds = now - (out->seconds * SEC_IN_USEC);
@ -205,19 +204,19 @@ static int _msg_wait(msg_t *m, msg_t *tmsg, xtimer_t *t)
}
}
int xtimer_msg_receive_timeout64(msg_t *m, uint64_t timeout) {
int _xtimer_msg_receive_timeout64(msg_t *m, uint64_t timeout_ticks) {
msg_t tmsg;
xtimer_t t;
_setup_timer_msg(&tmsg, &t);
xtimer_set_msg64(&t, timeout, &tmsg, sched_active_pid);
_xtimer_set_msg64(&t, timeout_ticks, &tmsg, sched_active_pid);
return _msg_wait(m, &tmsg, &t);
}
int xtimer_msg_receive_timeout(msg_t *msg, uint32_t us)
int _xtimer_msg_receive_timeout(msg_t *msg, uint32_t timeout_ticks)
{
msg_t tmsg;
xtimer_t t;
_setup_timer_msg(&tmsg, &t);
xtimer_set_msg(&t, us, &tmsg, sched_active_pid);
_xtimer_set_msg(&t, timeout_ticks, &tmsg, sched_active_pid);
return _msg_wait(msg, &tmsg, &t);
}

View File

@ -69,21 +69,21 @@ static inline void xtimer_spin_until(uint32_t target) {
void xtimer_init(void)
{
/* initialize low-level timer */
timer_init(XTIMER_DEV, XTIMER_USEC_TO_TICKS(1000000ul), _periph_timer_callback, NULL);
timer_init(XTIMER_DEV, XTIMER_HZ, _periph_timer_callback, NULL);
/* register initial overflow tick */
_lltimer_set(0xFFFFFFFF);
}
static void _xtimer_now64(uint32_t *short_term, uint32_t *long_term)
static void _xtimer_now_internal(uint32_t *short_term, uint32_t *long_term)
{
uint32_t before, after, long_value;
/* loop to cope with possible overflow of xtimer_now() */
/* loop to cope with possible overflow of _xtimer_now() */
do {
before = xtimer_now();
before = _xtimer_now();
long_value = _long_cnt;
after = xtimer_now();
after = _xtimer_now();
} while(before > after);
@ -91,10 +91,10 @@ static void _xtimer_now64(uint32_t *short_term, uint32_t *long_term)
*long_term = long_value;
}
uint64_t xtimer_now64(void)
uint64_t _xtimer_now64(void)
{
uint32_t short_term, long_term;
_xtimer_now64(&short_term, &long_term);
_xtimer_now_internal(&short_term, &long_term);
return ((uint64_t)long_term<<32) + short_term;
}
@ -104,7 +104,7 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
DEBUG(" _xtimer_set64() offset=%" PRIu32 " long_offset=%" PRIu32 "\n", offset, long_offset);
if (!long_offset) {
/* timer fits into the short timer */
xtimer_set(timer, (uint32_t) offset);
_xtimer_set(timer, (uint32_t) offset);
}
else {
int state = irq_disable();
@ -112,7 +112,7 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
_remove(timer);
}
_xtimer_now64(&timer->target, &timer->long_target);
_xtimer_now_internal(&timer->target, &timer->long_target);
timer->target += offset;
timer->long_target += long_offset;
if (timer->target < offset) {
@ -126,7 +126,7 @@ void _xtimer_set64(xtimer_t *timer, uint32_t offset, uint32_t long_offset)
}
}
void xtimer_set(xtimer_t *timer, uint32_t offset)
void _xtimer_set(xtimer_t *timer, uint32_t offset)
{
DEBUG("timer_set(): offset=%" PRIu32 " now=%" PRIu32 " (%" PRIu32 ")\n", offset, xtimer_now(), _xtimer_lltimer_now());
if (!timer->callback) {
@ -137,11 +137,11 @@ void xtimer_set(xtimer_t *timer, uint32_t offset)
xtimer_remove(timer);
if (offset < XTIMER_BACKOFF) {
xtimer_spin(offset);
_xtimer_spin(offset);
_shoot(timer);
}
else {
uint32_t target = xtimer_now() + offset;
uint32_t target = _xtimer_now() + offset;
_xtimer_set_absolute(timer, target);
}
}
@ -164,18 +164,12 @@ static inline void _lltimer_set(uint32_t target)
return;
}
DEBUG("_lltimer_set(): setting %" PRIu32 "\n", _xtimer_lltimer_mask(target));
#ifdef XTIMER_SHIFT
target = XTIMER_USEC_TO_TICKS(target);
if (!target) {
target++;
}
#endif
timer_set_absolute(XTIMER_DEV, XTIMER_CHAN, _xtimer_lltimer_mask(target));
}
int _xtimer_set_absolute(xtimer_t *timer, uint32_t target)
{
uint32_t now = xtimer_now();
uint32_t now = _xtimer_now();
int res = 0;
DEBUG("timer_set_absolute(): now=%" PRIu32 " target=%" PRIu32 "\n", now, target);
@ -309,7 +303,7 @@ static uint32_t _time_left(uint32_t target, uint32_t reference)
static inline int _this_high_period(uint32_t target) {
#if XTIMER_MASK
return (target & XTIMER_MASK_SHIFTED) == _xtimer_high_cnt;
return (target & XTIMER_MASK) == _xtimer_high_cnt;
#else
(void)target;
return 1;
@ -413,7 +407,7 @@ static void _next_period(void)
{
#if XTIMER_MASK
/* advance <32bit mask register */
_xtimer_high_cnt += ~XTIMER_MASK_SHIFTED + 1;
_xtimer_high_cnt += ~XTIMER_MASK + 1;
if (_xtimer_high_cnt == 0) {
/* high_cnt overflowed, so advance >32bit counter */
_long_cnt++;

View File

@ -68,7 +68,7 @@ int main(void)
random_init(myseed);
unsigned long t1 = xtimer_now();
unsigned long t1 = xtimer_now_usec();
for (int i = 0; i < lenB; i++) {
buf_fill(buf, BUF_SIZE);
@ -78,14 +78,14 @@ int main(void)
BUF_SIZE * sizeof(uint32_t) / sizeof(uint8_t));
}
unsigned long t2 = xtimer_now();
unsigned long t2 = xtimer_now_usec();
printf("adding %d elements took %" PRIu32 "ms\n", lenB,
(uint32_t) (t2 - t1) / 1000);
int in = 0;
int not_in = 0;
unsigned long t3 = xtimer_now();
unsigned long t3 = xtimer_now_usec();
for (int i = 0; i < lenA; i++) {
buf_fill(buf, BUF_SIZE);
@ -101,7 +101,7 @@ int main(void)
}
}
unsigned long t4 = xtimer_now();
unsigned long t4 = xtimer_now_usec();
printf("checking %d elements took %" PRIu32 "ms\n", lenA,
(uint32_t) (t4 - t3) / 1000);

View File

@ -30,7 +30,7 @@ int main(void)
{
int res;
bh1750fvi_t dev;
uint32_t last = xtimer_now();
xtimer_ticks32_t last = xtimer_now();
puts("BH1750FVI ambient light sensor test\n");

View File

@ -46,7 +46,7 @@ static color_rgb_t leds[LPD8808_PARAM_LED_CNT];
int main(void)
{
uint32_t now = xtimer_now();
xtimer_ticks32_t now = xtimer_now();
int pos = 0;
int step = 1;
color_hsv_t col = { 0.0, 1.0, 1.0 };

View File

@ -75,7 +75,7 @@ static int cmd_sample(int argc, char **argv)
{
(void)argc;
(void)argv;
uint32_t wakeup = xtimer_now();
xtimer_ticks32_t wakeup = xtimer_now();
while(1) {
sample();

View File

@ -31,7 +31,7 @@
int main(void)
{
uint32_t last = xtimer_now();
xtimer_ticks32_t last = xtimer_now();
int sample = 0;
puts("\nRIOT ADC peripheral driver test\n");

View File

@ -30,7 +30,7 @@
int main(void)
{
uint32_t last = xtimer_now();
xtimer_ticks32_t last = xtimer_now();
uint16_t val = 0;
uint16_t step = 0xffff / STEPS;

View File

@ -42,7 +42,7 @@ int main(void)
{
int state = 0;
int step = STEP;
uint32_t last_wakeup = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
puts("\nRIOT PWM test");
puts("Connect an LED or scope to PWM pins to see something\n");

View File

@ -242,14 +242,14 @@ void test4(void)
struct timespec abs;
uint64_t now, start, stop;
const uint64_t exp = 1000000;
now = xtimer_now64();
now = xtimer_now_usec64();
abs.tv_sec = (time_t)((now / SEC_IN_USEC) + 1);
abs.tv_nsec = (long)((now % SEC_IN_USEC) * 1000);
puts("first: sem_init s1");
if (sem_init(&s1, 0, 0) < 0) {
puts("first: sem_init FAILED");
}
start = xtimer_now64();
start = xtimer_now_usec64();
puts("first: wait 1 sec for s1");
if (sem_timedwait(&s1, &abs) != 0) {
if (errno != ETIMEDOUT) {
@ -260,7 +260,7 @@ void test4(void)
puts("first: timed out");
}
}
stop = xtimer_now64() - start;
stop = xtimer_now_usec64() - start;
if ((stop < (exp - 100)) || (stop > (exp + 100))) {
fmt_u64_dec(uint64_str, stop);
printf("first: waited only %s usec => FAILED\n", uint64_str);

View File

@ -32,7 +32,7 @@
int main(void)
{
phydat_t res;
uint32_t last = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
puts("SAUL test application");
@ -50,7 +50,7 @@ int main(void)
dev = dev->next;
}
xtimer_periodic_wakeup(&last, INTERVAL);
xtimer_periodic_wakeup(&last_wakeup, INTERVAL);
}
return 0;

View File

@ -9,7 +9,7 @@ BOARD_INSUFFICIENT_MEMORY := airfy-beacon cc2650stk chronos msb-430 msb-430h pca
weio waspmote-pro nucleo-f072 arduino-uno \
arduino-duemilanove sodaq-autonomo arduino-zero \
nucleo-f030 nucleo-f070 nucleo-f091 pba-d-01-kw2x \
saml21-xpro microbit calliope-mini
saml21-xpro microbit calliope-mini limifrog-v1
USEMODULE += embunit

View File

@ -0,0 +1 @@
USEMODULE += div

View File

@ -15,7 +15,7 @@
#define ENABLE_DEBUG (0)
#include "debug.h"
static uint32_t u32_test_values[] = {
static const uint32_t u32_test_values[] = {
0,
1,
10,
@ -25,30 +25,63 @@ static uint32_t u32_test_values[] = {
(15625LU*5)+1,
0xffff,
0xffff<<10,
0xffffffff
0xffffffff,
};
static uint64_t u64_test_values[] = {
0xffffffffULL+1
static const uint64_t u64_test_values[] = {
11111111111ull,
0xffffffffull+1,
16383999997ull,
16383999998ull,
16383999999ull,
16384000000ull,
1048575999807ull,
1048575999808ull,
1048575999809ull,
0xffffffffffffeeull,
0x777777777777777ull,
0x1111111111111111ull,
0xffffffffffffffffull,
0x8000000000000000ull,
};
#define N_U32_VALS (sizeof(u32_test_values)/sizeof(uint32_t))
#define N_U64_VALS (sizeof(u64_test_values)/sizeof(uint64_t))
/* These expected values for test_div_u64_by_15625div512
* were computed from the expression (u64_test_values * 512) / 15625 using 128
* bit integers. */
static const uint64_t u64_15625_512_expected_values[] = {
364088888,
140737488,
536870911,
536870911,
536870911,
536870912,
34359738361,
34359738361,
34359738361,
2361183241434822,
17630168202713342,
40297527320487639,
604462909807314587,
302231454903657293,
};
#define N_U32_VALS (sizeof(u32_test_values)/sizeof(u32_test_values[0]))
#define N_U64_VALS (sizeof(u64_test_values)/sizeof(u64_test_values[0]))
static void test_div_u64_by_15625(void)
{
for (unsigned i = 0; i < N_U32_VALS; i++) {
DEBUG("Dividing %"PRIu32" by 15625...\n", u32_test_values[i]);
DEBUG("Dividing %12"PRIu32" by 15625...\n", u32_test_values[i]);
TEST_ASSERT_EQUAL_INT(
div_u64_by_15625(u32_test_values[i]),
u32_test_values[i]/15625);
(uint64_t)u32_test_values[i] / 15625,
div_u64_by_15625(u32_test_values[i]));
}
for (unsigned i = 0; i < N_U64_VALS; i++) {
DEBUG("Dividing %"PRIu64" by 15625...\n", u64_test_values[i]);
DEBUG("Dividing %12"PRIu64" by 15625...\n", u64_test_values[i]);
TEST_ASSERT_EQUAL_INT(
div_u64_by_15625(u64_test_values[i]),
u64_test_values[i]/15625);
(uint64_t)u64_test_values[i] / 15625,
div_u64_by_15625(u64_test_values[i]));
}
}
@ -57,8 +90,8 @@ static void test_div_u32_by_15625div512(void)
for (unsigned i = 0; i < N_U32_VALS; i++) {
DEBUG("Dividing %"PRIu32" by (15625/512)...\n", u32_test_values[i]);
TEST_ASSERT_EQUAL_INT(
div_u32_by_15625div512(u32_test_values[i]),
(uint64_t)u32_test_values[i]*512LU/15625);
(uint64_t)u32_test_values[i] * 512lu / 15625,
div_u32_by_15625div512(u32_test_values[i]));
}
}
@ -67,15 +100,32 @@ static void test_div_u64_by_1000000(void)
for (unsigned i = 0; i < N_U32_VALS; i++) {
DEBUG("Dividing %"PRIu32" by 1000000...\n", u32_test_values[i]);
TEST_ASSERT_EQUAL_INT(
div_u64_by_1000000(u32_test_values[i]),
u32_test_values[i]/1000000);
(uint64_t)u32_test_values[i] / 1000000lu,
div_u64_by_1000000(u32_test_values[i]));
}
for (unsigned i = 0; i < N_U64_VALS; i++) {
DEBUG("Dividing %"PRIu64" by 1000000...\n", u64_test_values[i]);
TEST_ASSERT_EQUAL_INT(
div_u64_by_1000000(u64_test_values[i]),
u64_test_values[i]/1000000U);
u64_test_values[i] / 1000000lu,
div_u64_by_1000000(u64_test_values[i]));
}
}
static void test_div_u64_by_15625div512(void)
{
for (unsigned i = 0; i < N_U32_VALS; i++) {
DEBUG("Dividing %"PRIu32" by (15625/512)...\n", u32_test_values[i]);
TEST_ASSERT_EQUAL_INT(
(uint64_t)u32_test_values[i] * 512lu / 15625,
div_u64_by_15625div512(u32_test_values[i]));
}
for (unsigned i = 0; i < N_U64_VALS; i++) {
DEBUG("Dividing %"PRIu64" by (15625/512)...\n", u64_test_values[i]);
TEST_ASSERT_EQUAL_INT(
u64_15625_512_expected_values[i],
div_u64_by_15625div512(u64_test_values[i]));
}
}
@ -84,6 +134,7 @@ Test *tests_div_tests(void)
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_div_u64_by_15625),
new_TestFixture(test_div_u32_by_15625div512),
new_TestFixture(test_div_u64_by_15625div512),
new_TestFixture(test_div_u64_by_1000000),
};

View File

@ -604,7 +604,7 @@ static void test_fib_15_get_lifetime(void)
add_buf_size - 1));
/* assuming some ms passed during these operations... */
now = xtimer_now64();
now = xtimer_now_usec64();
uint64_t cmp_lifetime = now + 900000lU;
uint64_t cmp_max_lifetime = now + 1100000lU;
@ -709,7 +709,7 @@ static void test_fib_16_prefix_match(void)
*/
static void test_fib_17_get_entry_set(void)
{
size_t addr_buf_size = 16;
static const size_t addr_buf_size = 16;
char addr_dst[addr_buf_size];
char addr_nxt[addr_buf_size];
@ -742,13 +742,12 @@ static void test_fib_17_get_entry_set(void)
arr_size = 20;
memset(prefix,0, addr_buf_size);
/* cppcheck: prefix is set to all 0 before adding an address
*/
/* cppcheck: prefix is set to all 0 before adding an address */
/* cppcheck-suppress redundantCopy */
snprintf(prefix, addr_buf_size, "Test address 0");
ret = fib_get_destination_set(&test_fib_table,
(uint8_t *)prefix, addr_buf_size-1,
(uint8_t *)prefix, addr_buf_size - 1,
&arr_dst[0], &arr_size);
TEST_ASSERT_EQUAL_INT(0, ret);
@ -756,11 +755,13 @@ static void test_fib_17_get_entry_set(void)
TEST_ASSERT_EQUAL_INT(20, arr_size);
arr_size = 20;
memset(prefix,0, addr_buf_size);
memset(prefix, 0, addr_buf_size);
/* cppcheck: prefix is set to all 0 before adding an address */
/* cppcheck-suppress redundantCopy */
snprintf(prefix, addr_buf_size, "Test address");
ret = fib_get_destination_set(&test_fib_table,
(uint8_t *)prefix, addr_buf_size-1,
(uint8_t *)prefix, addr_buf_size - 1,
&arr_dst[0], &arr_size);
TEST_ASSERT_EQUAL_INT(0, ret);

View File

@ -96,7 +96,8 @@ void *worker_thread(void *arg)
while (1) {
msg_t m;
msg_receive(&m);
uint32_t now = xtimer_now();
xtimer_ticks32_t ticks = xtimer_now();
uint32_t now = xtimer_usec_from_ticks(ticks);
if (start == 0) {
start = now;
last = start;
@ -105,18 +106,15 @@ void *worker_thread(void *arg)
}
uint32_t us, sec;
uint32_t min, hr;
us = now % SEC_IN_USEC;
sec = now / SEC_IN_USEC;
min = (sec / 60) % 60;
hr = sec / 3600;
if ((loop_counter % TEST_HZ) == 0) {
uint32_t expected = start + loop_counter * TEST_INTERVAL;
int32_t drift = now - expected;
expected = last + TEST_HZ * TEST_INTERVAL;
int32_t jitter = now - expected;
printf("now=%" PRIu32 ".%06" PRIu32 " (%" PRIu32 " hours %" PRIu32 " min), ",
sec, us, hr, min);
printf("now=%" PRIu32 ".%06" PRIu32 " (0x%08" PRIx32 " ticks), ",
sec, us, ticks.ticks32);
printf("drift=%" PRId32 " us, jitter=%" PRId32 " us\n", drift, jitter);
last = now;
}
@ -190,7 +188,7 @@ int main(void)
NULL,
"worker");
uint32_t last_wakeup = xtimer_now();
xtimer_ticks32_t last_wakeup = xtimer_now();
while (1) {
xtimer_periodic_wakeup(&last_wakeup, TEST_INTERVAL);
msg_try_send(&m, pid3);

View File

@ -76,8 +76,9 @@ int main(void)
NULL,
"timer2");
uint32_t end = xtimer_now() + TEST_TIME;
while(xtimer_now() < end)
xtimer_ticks32_t end = xtimer_now();
end.ticks32 += _xtimer_ticks_from_usec(TEST_TIME);
while(_xtimer_now() < end.ticks32)
{
count++;
xtimer_usleep(100LU * 1000);

View File

@ -96,7 +96,7 @@ void *mid_sleep(void *arg)
void *ticker(void *arg)
{
(void)arg;
uint32_t base = xtimer_now();
xtimer_ticks32_t base = xtimer_now();
while (1) {
++short_ticks;

View File

@ -82,11 +82,10 @@ void *timer_thread_local(void *arg)
msg_t m;
msg_receive(&m);
uint32_t now = xtimer_now();
int sec, min, hr;
sec = now/1000000;
min = sec/60;
hr = sec/3600;
uint32_t now = xtimer_now_usec();
int sec = now / 1000000;
int min = sec / 60;
int hr = sec / 3600;
printf("sec=%d min=%d hour=%d\n", sec, min, hr);
}
}

View File

@ -29,10 +29,10 @@
int main(void)
{
uint32_t n = ITERATIONS;
uint64_t before = xtimer_now64();
uint64_t before = _xtimer_now64();
while(--n) {
uint64_t now = xtimer_now64();
uint64_t now = _xtimer_now64();
if ((now-before) > MAXDIFF) {
puts("TEST FAILED.");
break;

View File

@ -37,13 +37,13 @@ int main(void)
int32_t min_diff = INT32_MAX;
for (int i = 0; i < NUMOF; i++) {
uint32_t now = xtimer_now();
printf("Testing interval %" PRIu32 "... (now=%" PRIu32 ")\n", interval, now);
uint32_t last_wakeup = xtimer_now();
uint32_t before = last_wakeup;
xtimer_ticks32_t now = xtimer_now();
printf("Testing interval %" PRIu32 "... (now=%" PRIu32 ")\n", interval, xtimer_usec_from_ticks(now));
xtimer_ticks32_t last_wakeup = xtimer_now();
xtimer_ticks32_t before = last_wakeup;
xtimer_periodic_wakeup(&last_wakeup, interval);
now = xtimer_now();
res[i] = (now - before) - interval;
res[i] = (xtimer_usec_from_ticks(now) - xtimer_usec_from_ticks(before)) - interval;
interval -= 1;
}

View File

@ -48,11 +48,11 @@ int main(void)
xtimer_set_wakeup(&xtimer, 200000, me);
xtimer_set_wakeup(&xtimer2, 100000, me);
printf("now=%" PRIu32 "\n", xtimer_now());
printf("now=%" PRIu32 "\n", xtimer_now_usec());
thread_sleep();
printf("now=%" PRIu32 "\n", xtimer_now());
printf("now=%" PRIu32 "\n", xtimer_now_usec());
thread_sleep();
printf("now=%" PRIu32 "\n", xtimer_now());
printf("now=%" PRIu32 "\n", xtimer_now_usec());
printf("Test completed!\n");