<re_irc>
<jessebraham> Question regarding drivers and power modes:
<re_irc>
I've implemented and/or worked on a number of drivers, but power modes have always been ignored. I'm working on an IMU driver now which has certain functionality which is only available in certain power modes. There are 6 total power modes, 2 of which do _not_ support certain functions.
<re_irc>
One solution is to just perform runtime checks of the currently configured power mode, however I would prefer to avoid this if possible. I thought that type states might be a good solution, but the function to change power modes using this approach would have to return "Result<Self, Error>" and then subsequently be re-assigned to a variable, which is not super ergonomic.
<re_irc>
Any suggestions on how to approach this?
<re_irc>
<GrantM11235> To make matters worse, you might need to return a "Result<NewSelf, (Error, OldSelf)>"
emerent has quit [Ping timeout: 272 seconds]
emerent has joined #rust-embedded
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
<re_irc>
<thalesfragoso> jessebraham: Maybe the "advanced mode" could borrow the "basic mode" instead of owning, but then you couldn't store them in the same place, which might suck
<re_irc>
<thalesfragoso> In embassy there's this Unborrow trait, that can work with both borrows and owned type in the same API, the type has to be a ZST though
<re_irc>
<thalesfragoso> It's used more to help with using the same peripheral for different things or configurations, e.g. when you want to change things on the fly you can just borrow the peripheral (and pay the unergonomic price) or you can pass it via ownership and your drive will be 'static
<re_irc>
<firefrommoonlight> (I'm using an IMU now btw, although don't use any low power modes; just some configuration in the constructor, then read all 6 measurements with a single DMA xfer whenever its interrupt pin is set)
<re_irc>
<firefrommoonlight> Or just don't set teh wrong mode
<re_irc>
<thalesfragoso> firefrommoonlight: They want to avoid runtime checks
<re_irc>
<firefrommoonlight> I mean what is the IMU being used for
<re_irc>
<firefrommoonlight> Avoiding runtime checks here is probably premature opt
<re_irc>
<thalesfragoso> firefrommoonlight: It seems to be a completely generic driver
<re_irc>
<firefrommoonlight> Yikes
fabic_ has joined #rust-embedded
<re_irc>
<jessebraham> It was more just a question of prior art, I could come up with a number of solutions that "work" but I'm curious what (if anything) the common approach to this is
<re_irc>
<jessebraham> Obviously the runtime checks are the easiest solution here, but again was just curious what alternatives are viable
<re_irc>
<James Munns> If it's a runtime condition, I'd probably go with runtime checks :p
<re_irc>
<James Munns> unless your code is simple/linear enough to be within one scope
<re_irc>
<jessebraham> Okay great, thank you
<re_irc>
<James Munns> I think you nailed the important part, making the compiler check something usually requires:
<re_irc>
Passing ownership (e.g. type states), which can make certain things hard, unless you have a REALLY particular program structure
<re_irc>
Using mut refs, which again, require a very particular program structure
<re_irc>
<James Munns> otherwise it really boils down to something like:
<re_irc>
<James Munns> enum Mode {
<re_irc>
Foo(Imu<ModeFoo>),
<re_irc>
Bar(Imu<ModeBar>),
<re_irc>
}
<re_irc>
Baz(Imu<ModeBaz>),
<re_irc>
<James Munns> more or less
<re_irc>
<James Munns> which, is just the runtime check inside-out
<re_irc>
<jessebraham> Right, thanks again for all that
causal has quit [Quit: WeeChat 3.5]
GenTooMan has quit [Ping timeout: 255 seconds]
GenTooMan has joined #rust-embedded
fabic_ has quit [Ping timeout: 246 seconds]
fabic_ has joined #rust-embedded
dc740 has joined #rust-embedded
starblue has quit [Ping timeout: 268 seconds]
starblue has joined #rust-embedded
GenTooMan has quit [Ping timeout: 268 seconds]
GenTooMan has joined #rust-embedded
talperud has quit [Remote host closed the connection]
GenTooMan has quit [Ping timeout: 240 seconds]
GenTooMan has joined #rust-embedded
fabic_ has quit [Ping timeout: 272 seconds]
fabic_ has joined #rust-embedded
explore has quit [Quit: Connection closed for inactivity]
fabic_ has quit [Ping timeout: 256 seconds]
fabic_ has joined #rust-embedded
<re_irc>
<Bob McWhirter> Anyone seen this weird error using heapless 0.7.14?
<Lumpio->
I think that might be its way of telling you that your parameters have to be a power of two
<Lumpio->
What are you passing the constant 5 to?
<Lumpio->
Maybe you're using IndexMap or IndexSet?
<re_irc>
<James Munns> Yeah, Bob McWhirter some of the collections/queues have restrictions on the size (e.g. must be >= some min size, must be a power of two), definitely check the docs for the type you're using!
<Lumpio->
heapless seems to target an old Rust compiler which doesn't have compile time panic! support yet so the message isn't the best
<re_irc>
<Lachlan> I don’t think asserting on a const generic is stable even in the latest version
<Lumpio->
Ah, alright
<Lumpio->
I seem to remember const panic! being a thing though but I guess there's a limitation as usual
<re_irc>
<Lachlan> OH, like that. I was thinking in the generic bounds, but I guess that still counts
<re_irc>
<Lachlan> I stand corrected
<re_irc>
<thalesfragoso> James Munns: Unless the user only wants to use one mode, then they wouldn't need an enum nor runtime checks (if using type states)
<re_irc>
<thalesfragoso> ps: I'm not advocating for type stating everything
<re_irc>
<James Munns> Yeah, sorry, I meant specifically in cases where you want to change the states at run time
<re_irc>
<thalesfragoso> Or even this case in specific
crabbedhaloablut has quit [Remote host closed the connection]
crabbedhaloablut has joined #rust-embedded
causal has joined #rust-embedded
<re_irc>
<Lachlan> Do y'all know how close we are to GATs/async trait methods being stabilized?
<re_irc>
<James Munns> It's in "intense conversation" atm
<re_irc>
<James Munns> so, months, at least.
<re_irc>
<Lachlan> Ah, well that's understandable
<re_irc>
<Lachlan> Is there a rundown somewhere of what is still being debated?
<re_irc>
<omar_u8> I've been experimenting with HAL counter implementations recently. It seems that although all timers share traits of input capture, output compare, and PWM not all are implemented. Some HALs from what it seems implement a restricted version of some functionality like input compare through what is referred to as PWMinput. Additionally, when looking into the embedded-HAL documentation I did find a Capture trait though...
<re_irc>
... with the following note
<re_irc>
> This trait is available if embedded-hal is built with the "unproven" feature."
<re_irc>
Which I am not sure what that is supposed to mean. Additionally, even with that trait, options like capture on a positive or negative edge don't seem to be existent. I'm curious as to the reasoning behind that.
<re_irc>
<firefrommoonlight> Sry; I haven't implemented input capture yet since it hasn't come up
<re_irc>
<firefrommoonlight> On the todo list somewhere lol
<re_irc>
<firefrommoonlight> Sry; I haven't implemented input capture yet since it hasn't come up on anything I've worked on
<re_irc>
<omar_u8> That makes me feel better, I thought there was something deep that I was really missing lol
<re_irc>
<omar_u8> What is the "unproven" feature though?
<re_irc>
<omar_u8> I've been experimenting with HAL counter implementations recently. It seems that although all timers share traits of input capture, output compare, and PWM not all are implemented. Some HALs from what it seems implement a restricted version of some functionality like input capture through what is referred to as PWMinput. Additionally, when looking into the embedded-HAL documentation I did find a Capture trait though...
<re_irc>
... with the following note
<re_irc>
> This trait is available if embedded-hal is built with the "unproven" feature."
<re_irc>
Which I am not sure what that is supposed to mean. Additionally, even with that trait, options like capture on a positive or negative edge don't seem to be existent. I'm curious as to the reasoning behind that.
<re_irc>
<omar_u8> Another question, I recall once seeing a page with sort of green bars indicating the level of completeness of that different HALs. I didn't bookmark the link and I've been looking for it ever since.
<re_irc>
<firefrommoonlight> omar_u8: EH jargon for a todo
<re_irc>
<firefrommoonlight> * something that hasn't been agreed upon by relevant parties
fabic_ has quit [Ping timeout: 246 seconds]
<re_irc>
<Bob McWhirter> James Munns: It seems for any positive value of "L" in this case, though, it'll overflow (underflow? Zero minus... into "usize")
<re_irc>
<James Munns> It's just a weird compile time trick to make sure it's a power of two
explore has joined #rust-embedded
<re_irc>
<James Munns> like indexing
<re_irc>
"[0u8; 1][N.next_power_of_two() - N]"
<re_irc>
<James Munns> it's like old school "static assert" tricks in C
<re_irc>
<James Munns> Indexing any value other than "0" panics, so if "N" isn't a power of two, the code panics and const time,
Guest9654 has joined #rust-embedded
Guest9654 has left #rust-embedded [#rust-embedded]
crabbedhaloablut has quit [Remote host closed the connection]
<re_irc>
<firefrommoonlight> If anyone has a use case (I see someone ask for it every few weeks), testing would be appreciated!
<re_irc>
<firefrommoonlight> I may have a use case soon too, but not ready yet (Bidirectional DSHOT motor protocol, werein you read a duty-cycle-based digital protocol that's PWM-like)
<re_irc>
<firefrommoonlight> I have the writes working for it, (timer burst DMA), but not the reads