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:
commit
84d0d61279
@ -535,6 +535,7 @@ endif
|
||||
|
||||
ifneq (,$(filter xtimer,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_timer
|
||||
USEMODULE += div
|
||||
endif
|
||||
|
||||
ifneq (,$(filter saul_reg,$(USEMODULE)))
|
||||
|
@ -73,6 +73,7 @@ extern "C" {
|
||||
*/
|
||||
#define XTIMER_WIDTH (16)
|
||||
#define XTIMER_SHIFT (2)
|
||||
#define XTIMER_HZ (250000UL)
|
||||
#define XTIMER_BACKOFF (40)
|
||||
/** @} */
|
||||
|
||||
|
@ -69,6 +69,7 @@ extern "C" {
|
||||
*/
|
||||
#define XTIMER_WIDTH (16)
|
||||
#define XTIMER_SHIFT (2)
|
||||
#define XTIMER_HZ (250000UL)
|
||||
#define XTIMER_BACKOFF (40)
|
||||
/** @} */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
/** @} */
|
||||
|
@ -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)
|
||||
/** @} */
|
||||
|
@ -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)
|
||||
/** @} */
|
||||
|
@ -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)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
1
sys/div/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
46
sys/div/div.c
Normal file
46
sys/div/div.c
Normal 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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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) */
|
||||
|
138
sys/include/xtimer/tick_conversion.h
Normal file
138
sys/include/xtimer/tick_conversion.h
Normal 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
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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 };
|
||||
|
@ -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();
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
1
tests/unittests/tests-div/Makefile.include
Normal file
1
tests/unittests/tests-div/Makefile.include
Normal file
@ -0,0 +1 @@
|
||||
USEMODULE += div
|
@ -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),
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user