LogEtComUSB/lib/sd_driver/delays.h

80 lines
1.8 KiB
C

/*
* delays.h
*
* Created on: Apr 25, 2022
* Author: carlk
*/
/* Using millis() or micros() for timeouts
For example,
uint32_t start = millis();
do {
// ...
}
} while (millis() - start < TIMEOUT);
There is no problem if the millis() counter wraps,
due to the properties of unsigned integer modulo arithmetic.
"A computation involving unsigned operands can never overflow,
because a result that cannot be represented by the resulting
unsigned integer type is reduced modulo the number that is
one greater than the largest value that can be represented
by the resulting type."
-- ISO/IEC 9899:1999 (E) §6.2.5/9
In other words, a uint32_t will wrap at 0 and UINT_MAX.
So, for example,
0x00000000 - 0xFFFFFFFF = 0x00000001
Remember that an unsigned integer will never be negative!
Be careful with comparisons. In the example above,
if 0x00000000 is the result of the counter wrapping,
and 0xFFFFFFFF is the start timestamp, a comparison like
millis() - start < TIMEOUT
is OK, but the following code is problematic if, say, the first call
to millis() returns 0xFFFFFFF0 and the second
call to millis() returns 0xFFFFFFFF:
uint32_t end = millis() + 100; // end = 0x00000054
while (millis() < end) // while (0xFFFFFFFF < 0x00000054)
*/
#pragma once
#include <stdint.h>
//
#include "pico.h"
#include "pico/stdlib.h"
#ifdef __cplusplus
extern "C" {
#endif
static inline uint32_t millis() {
__compiler_memory_barrier();
return time_us_64() / 1000;
__compiler_memory_barrier();
}
static inline void delay_ms(uint32_t ulTime_ms) {
sleep_ms(ulTime_ms);
}
static inline uint64_t micros() {
__compiler_memory_barrier();
return to_us_since_boot(get_absolute_time());
__compiler_memory_barrier();
}
#ifdef __cplusplus
}
#endif
/* [] END OF FILE */