<re_irc> <@lachlansneff:matrix.org> Just on and off, no pwm or analog needed
starblue has quit [Ping timeout: 260 seconds]
starblue has joined #rust-embedded
emerent_ has joined #rust-embedded
emerent is now known as Guest6618
emerent_ is now known as emerent
Guest6618 has quit [Ping timeout: 268 seconds]
fabic has joined #rust-embedded
PyroPeter has quit [Ping timeout: 240 seconds]
PyroPeter has joined #rust-embedded
troth has quit [Ping timeout: 256 seconds]
troth has joined #rust-embedded
fabic has quit [Ping timeout: 256 seconds]
<re_irc> <@henrik_alser:matrix.org> lachlansneff:matrix.org: What kind of electrodes and what are they connected to?
<re_irc> <@firefrommoonlight:matrix.org> Re STM32 DMA: Make the buffer a `static mut`, and pass it as a pointer in the DMA config
<re_irc> <@firefrommoonlight:matrix.org> To make it a double buffer, make it twice the size of the block size (Since this is I2S audio, you likely want 4x the size, since the L/R channels are interleaved)
<re_irc> <@firefrommoonlight:matrix.org> Use DMA half and full transfer interrupts to swap the halves
nohit has quit [Ping timeout: 264 seconds]
nohit has joined #rust-embedded
<re_irc> <@whitequark:matrix.org> so, someone will send me an MSP432P devboard
<re_irc> <@whitequark:matrix.org> (previously discussed here: https://freenode.logbot.info/rust-embedded/20201104)
<re_irc> <@whitequark:matrix.org> <del>maybe i should add probe-rs support</del>
fabic has joined #rust-embedded
tafa has quit [Quit: ZNC - https://znc.in]
tafa has joined #rust-embedded
<re_irc> <@luojia65:matrix.org> check out the w806-pac rust docs:
<re_irc> <@luojia65:matrix.org> by now the RCC peripheral is finished (a lot of work on svd files)
cr1901 has quit [Read error: Connection reset by peer]
cr1901 has joined #rust-embedded
cr1901 has quit [Read error: Connection reset by peer]
cr1901 has joined #rust-embedded
<re_irc> <@thejpster:matrix.org> Are you handwriting the whole SVD from scratch?
fabic has quit [Ping timeout: 260 seconds]
<re_irc> <@grantm11235:matrix.org> Still thinkin' about ~~those beans~~ my spi `Chipselect` trait
<re_irc> <@grantm11235:matrix.org> ```rust
<re_irc> <@grantm11235:matrix.org> pub trait Chipselect {
<re_irc> <@grantm11235:matrix.org> fn with_chipselect(&mut self, f: impl FnOnce(&mut Self::Inner));
<re_irc> <@grantm11235:matrix.org> }
<re_irc> <@grantm11235:matrix.org> type Inner;
<re_irc> <@grantm11235:matrix.org> I would like to be able to enforce the following rules:
<re_irc> <@grantm11235:matrix.org> 1. If `T: Chipselect` and `T::Inner: Write`, then `T: Write` using a blanket impl
<re_irc> <@grantm11235:matrix.org> 2. If `T: Chipselect` but `T::Inner: !Write`, then `T: !Write`
<re_irc> <@grantm11235:matrix.org> 4. Downstream crates can only impl `Write` for types that do not impl `Chipselect`
<re_irc> <@grantm11235:matrix.org> 3. If `T: Chipselect + Write` then `T::Inner: Write`
<re_irc> <@grantm11235:matrix.org> Is that possible with rust's trait system?
<re_irc> <@grantm11235:matrix.org> By the way, if this works I am pretty sure that it would solve the default methods problem in https://github.com/rust-embedded/embedded-hal/pull/323
<re_irc> <@ubik:matrix.org> what's the "right" way to check for `.get_half_transfer_flag()` in a DMA stream? I can access a `Transfer` object from my ISR, which has a `get_stream()` method, but I see that its usage is discouraged
<re_irc> <@ubik:matrix.org> never mind... `Stream4::get_half_transfer_flag()`
<re_irc> <@ubik:matrix.org> doh.
<re_irc> <@firefrommoonlight:matrix.org> You may not even need to check the flag; you can configure the interrupt instead
<re_irc> <@firefrommoonlight:matrix.org> (Depends on specifics)
<re_irc> <@firefrommoonlight:matrix.org> *Actually nvm you still need to check the flag to figure out if it's the half transfer or full, since they share the same ISR
<re_irc> <@ryankurte:matrix.org> grantm11235:matrix.org: you can't do !trait atm afaik, though maybe there's a workaround
<re_irc> <@grantm11235:matrix.org> I was just using `!trait` as a shorthand
<re_irc> <@ryankurte:matrix.org> same, last i looked there was a pre-rfc but no functional equivalent
<re_irc> <@ryankurte:matrix.org> grantm11235:matrix.org: so the idea here is that _if_ you had a ChipSelect type you'd call with_chipselect and do your ops inside the closure?
<re_irc> <@grantm11235:matrix.org> grantm11235:matrix.org: I think that #2 is just a rephrased version of #4
<re_irc> <@grantm11235:matrix.org> ryankurte:matrix.org: You would only need to use `with_chipselect` for complicated stuff, other wise you would just use `Chipselect` as a marker trait
<re_irc> <@grantm11235:matrix.org> Here are some examples that I am playing with right now https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=edad53daff8047a6f8b9f013ec793584
<re_irc> <@ryankurte:matrix.org> ooooh, that's neat! so it's basically the marker trait + `with_cs` for manual combining of things if required?
<re_irc> <@ryankurte:matrix.org> that resolves one issue i had which was the need to spi write -> wait for pin assert -> spi read within a single transaction
<re_irc> <@grantm11235:matrix.org> It also makes it really easy to make spi mutex types
<re_irc> <@grantm11235:matrix.org> You just impl `Chipselect` for it, and you get everything else for free
<re_irc> <@ryankurte:matrix.org> ahh interesting, i wouldn't worry too much about making that specifically easier? it might work out to be worth it but, there also aren't that many spi mutexes so, not at the cost of anything else
<re_irc> <@ryankurte:matrix.org> for `with_cs` would it make sense to pass a return up so you can still bubble errors?
<re_irc> <@ryankurte:matrix.org> something like: `fn with_cs<R, F: FnMut(&mut Self) -> R>(&mut self, f: F) -> R;`
<re_irc> <@grantm11235:matrix.org> Yeah, I just removed that from my simplified example
<re_irc> <@ryankurte:matrix.org> i think it needs to be a fnmut so you can capture outer variables too
<re_irc> <@grantm11235:matrix.org> Doesn't FnOnce allow you to do that too?
<re_irc> <@ryankurte:matrix.org> will have to try destructuring to see if i can work out how to get both spi and pin control into the closure
<re_irc> <@ryankurte:matrix.org> grantm11235:matrix.org: ah i think you're right! my misunderstanding of FnOnce
<re_irc> <@grantm11235:matrix.org> I'm not sure what to do about fallible CS pins though, I don't think that it is enough to just bubble up the error
<re_irc> <@ryankurte:matrix.org> ahh, there'd need to be an error bound too eh. not sure there's much more one could do?
<re_irc> <@grantm11235:matrix.org> If asserting or deasserting cs fails, that means that your cs pin is in an unknowns state, and it is important not to do anything else on the bus until you sort that out
<re_irc> <@ryankurte:matrix.org> also not sure whether spidev gives us an ioctl to manually assert/deassert CS, need to work out whether that's implementable
<re_irc> <@ryankurte:matrix.org> grantm11235:matrix.org: is that specifically worse than any other failure? in any case it's a bad day
<re_irc> <@grantm11235:matrix.org> I guess that an spi mutex would need some sort of poisoned flag to detect if another device on the bus failed to (de)assert cs
<re_irc> <@ubik:matrix.org> firefrommoonlight:matrix.org: Actually, I just used double buffering instead and it seems to be working out of the box
<re_irc> <@grantm11235:matrix.org> But it would be much easier to just panic or only accept infallible cs pins
emerent_ has joined #rust-embedded
emerent has quit [Ping timeout: 268 seconds]
emerent_ is now known as emerent
<re_irc> <@grantm11235:matrix.org> grantm11235:matrix.org: By the way, note that `Write` has a new method called `write_multi` with a default impl. Because the `Chipselect` blanket impl overrides it, downstream crates can safely ignore it without accidentally breaking any promises
<re_irc> <@grantm11235:matrix.org> That is how it solves the default method problem in https://github.com/rust-embedded/embedded-hal/pull/323
<re_irc> <@ryankurte:matrix.org> ahh interesting, so you'd override any of the defaults proposed in #323, and implementing ManagedCS would only require that one `with_cs` function?
<re_irc> <@grantm11235:matrix.org> A downstream crate could technically still get in to trouble if it manually impl'd `Chipselect` and `Write` for the same type, but I think that is only possible if `T::Inner: !Write`
<re_irc> <@ryankurte:matrix.org> what's the reasoning behind the associated `Inner` type?
<re_irc> <@ryankurte:matrix.org> naively seems like it'd work without
<re_irc> <@grantm11235:matrix.org> grantm11235:matrix.org: Actually, it is not possible to manually impl `Chipselect` and `Write`. rustc says that the `Write` impl collides with the blanket impl even if `Inner` does not impl `Write`
<re_irc> <@ryankurte:matrix.org> (also great work! super interesting option, definitely worth getting to a PR / demonstration. only overarching comment is, the simpler the better when it comes to traits so aim for this as much as possible)
<re_irc> <@grantm11235:matrix.org> ryankurte:matrix.org: What would the closure take? I don't think that `&mut Self` would work
<re_irc> <@grantm11235:matrix.org> And you can't use the spi proxy inside the closure because `with_cs` takes `&mut self`
<re_irc> <@ryankurte:matrix.org> seems okay?
<re_irc> <@ryankurte:matrix.org> (tho obvs that's not an outside call)
<re_irc> <@grantm11235:matrix.org> Interesting, I'll have to try that out
<re_irc> <@grantm11235:matrix.org> Well it definitely breaks the blanket impl because you can't do `impl<T: Chipselect + Write> Write for T`
<re_irc> <@ryankurte:matrix.org> ahhh, i see
<re_irc> <@grantm11235:matrix.org> Well I already forgot to override the `write_multi` impl, I think that might be too much of a footgun 🤣
<re_irc> <@ryankurte:matrix.org> just playing with this too
<re_irc> <@grantm11235:matrix.org> I manually impl'd `write` for my shared spi struct, but it still doesn't work right https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=6e29077ee9862d326e7147ee81eb250a
<re_irc> <@grantm11235:matrix.org> In order to do stuff inside the closure without touching cs, you need access to the inner bus struct
<re_irc> <@grantm11235:matrix.org> Alternatively, we could decide that the `Write` trait never touches cs by it's self and you always need to use the `with_cs` method. That doesn't seem as ergonomic though
<re_irc> <@ryankurte:matrix.org> yeah i see the problem, Inner makes sense there, thanks for humoring me!
<re_irc> <@grantm11235:matrix.org> Thanks for the suggestion!
<re_irc> <@grantm11235:matrix.org> Overall, I am pretty happy with what I have so far EXCEPT for the fact that I had to remove the blanket `&mut T` impls to get it to work
<re_irc> <@ryankurte:matrix.org> grantm11235:matrix.org: ahh i ran into this too
<re_irc> <@grantm11235:matrix.org> It would also work if I removed the `Chipselect` blanket impls, but those are what solve the default method problem
<re_irc> <@grantm11235:matrix.org> Would specialization solve this somehow?
<re_irc> <@ryankurte:matrix.org> does dropping the default methods work? because that seems like a fine solution to me
<re_irc> <@ryankurte:matrix.org> it's a wee bit more work on the HAL side, but seems easier to rationalise about at that
<re_irc> <@grantm11235:matrix.org> ryankurte:matrix.org: That would work, but we would lose the ability to add methods to `Write` as a non-breaking change
<re_irc> <@grantm11235:matrix.org> That is probably the best compromise if there isn't a way for both sets of blanket impls to coexist
<re_irc> <@grantm11235:matrix.org> The other nice thing about the blanket impl is that if `T: Chipselect` and `T::Inner: Write`, then rustc knows that `T: Write`
<re_irc> <@grantm11235:matrix.org> Without it, you would either need to
<re_irc> <@grantm11235:matrix.org> - make your trait bound `T: Chipselect + Write, T::Inner: Write` (seems redundant)
<re_irc> <@grantm11235:matrix.org> - or use `T: Chipselect, T::Inner: Write` and use `with_cs` for every write call (not very ergonomic)
<re_irc> <@grantm11235:matrix.org> - or use `T: Chipselect + Write` and not be able to use `with_cs` for anything more complicated
<re_irc> <@grantm11235:matrix.org> `T: Chipselect + Write` seems the cleanest, so it would be really nice if there was a way to convince rustc that this also implicitly means `T::Inner: Write`
<re_irc> <@grantm11235:matrix.org> "For all `T: Chipselect`, `T: Write` if and only if `T::Inner: Write`"