-
Notifications
You must be signed in to change notification settings - Fork 134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make modm::delay compatible with std::chrono #374
Conversation
aa3b111
to
968e6a1
Compare
I'm ready to merge this if there are no complaints. I don't think this is very controversial, except perhaps the deprecation of delayMilliseconds etc. Is this deprecation too annoying? I could also make it silently forward to the new functions and simply not document these methods, so that new users don't use them. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree on deprecating delayMilliseconds
.
Maybe we should fix AVR delay_ns
. The way it is implemented right now delay_ns(1000)
is a no-op, which is kind of surprising. There is a new instrinsic in avr-gcc which could help. It only works on compile time known delays and with optimization turned on, though.
I have tried it and it seems to work fine here.
I know, and I explicitly chose the dynamic implementation with void
_delay_us(double __us)
{
double __tmp ;
uint8_t __ticks;
double __tmp2 ;
__tmp = ((F_CPU) / 3e6) * __us;
__tmp2 = ((F_CPU) / 4e6) * __us;
if (__tmp < 1.0)
__ticks = 1;
else if (__tmp2 > 65535)
{
_delay_ms(__us / 1000.0);
}
else if (__tmp > 255)
{
uint16_t __ticks=(uint16_t)__tmp2;
_delay_loop_2(__ticks);
return;
}
else
__ticks = (uint8_t)__tmp;
_delay_loop_1(__ticks);
} |
I need to implement this myself it seems, and then I can hack something much more useful together with |
I just wanted to try the horrible runtime version in compiler explorer and found out
for
Maybe we never noticed that this doesn't work anymore because in modm all delays are static. I don't have a C++17 compatible avr-gcc here right now to test with modm. |
Oh, sorry. It works with |
This is what I came up with. I tried it with I mean, the fastest this thing will ever go is 32MHz, which is 93ns per loop. At 8MHz, it's 375ns per loop. So the runtime version will be hopelessly over the top. |
Seems reasonable. The line
Don't worry, 3 cycles is still a lot better than the 32 bit float multiplication in avr-libc. If someone wants accurate nanosecond timings, they should choose a faster cpu. |
968e6a1
to
5cf8a08
Compare
This makes the :platform:clock module optional as it should be.
This prevents the automatic inclusion into <modm/platform.hpp> and thus prevents include ordering issues.
16302fc
to
f6118fa
Compare
I've implemented a new AVR delay that uses Testing suggests that dynamic ms and us delay are fairly accurate even over an accumulated period, but dynamic ns delay is not super accurate, but also not wildly off. I think this is fine for most applications. |
f6118fa
to
b010775
Compare
This adds std::chrono support for the
modm::delay()
blocking delay implementation.The implementation duration_casts everything to microseconds by default, unless a specialization is provided:
modm::delay(std::chrono::nanoseconds)
,modm::delay_ns(uint32_t)
: Only implemented for Cortex-M, AVRs always delays 1us, Hosted casts to us (darwin/linux) or ms (windows).modm::delay(std::chrono::microseconds)
,modm::delay_us(uint32_t)
: implemented for all, except windows (casts to ms).modm::delay(std::chrono::milliseconds)
,modm::delay_ms(uint32_t)
: implemented for AVR and Hosted. Cortex-M casts to us.In order to not go crazy from adding
using namespace std::chrono_literals
, I've added this to<modm/board.hpp>
with a guard macroMODM_BOARD_DO_NOT_USE_LITERALS
, so you can disable this behavior in your code. (It also addsusing namespace modm::literals
).I have a usability question: Shouldmodm::delayMilliseconds(uint16_t)
be deprecated? During my refactoring, I had to add a lot ofusing namespace std::chrono_literals
to driver methods, or construct thestd::chrono::milliseconds(uint)
in place. This is a little verbose. Perhaps the previous methods weren't such a bad idea? Should they perhaps be renamed tomodm::delay_ms()
for consistency?Update: I've added
modm::delay_[mun]s()
functions as well, and it make perfect sense and the naming is good too.TODO:
cc @rleh @se-bi @strongly-typed @chris-durand
This PR is in preparation for #217.