<re_irc>
<disasm> silvergasp: Except for proprietary interrupt system which tries to mimic Cortex-M and a few non-standard modes of operation
<re_irc>
<disasm> thalesfragoso: I wish it was a copy, it has a different IP core version which is not compatible with the ones in F4, but quite similar
<re_irc>
<Lachlan> My dream is that chip fabrication becomes much cheaper and we can all contribute to a set of open-source cores that compete based on merit
<re_irc>
<Lachlan> Oops, wrong chat lol
Socke has quit [*.net *.split]
fooker has quit [*.net *.split]
Socke has joined #rust-embedded
fooker has joined #rust-embedded
nohit has quit [*.net *.split]
dreamcat4 has quit [*.net *.split]
eigenform has quit [*.net *.split]
eigenform has joined #rust-embedded
dreamcat4 has joined #rust-embedded
nohit has joined #rust-embedded
explore has joined #rust-embedded
dc740 has quit [Remote host closed the connection]
causal has quit [Quit: WeeChat 3.5]
<re_irc>
<hartan> Hello,
<re_irc>
I'm trying to implement the spi traits from "embedded hal 1.0.0-alpha.8" for the Espressif ESP32 family of devices. To that end I'm looking for some examples/existing implementations to use as starting point since a few things about the current description confuse me. Are there existing implementations I can look at?
<re_irc>
<9names (@9names:matrix.org)> keep in mind that by "alpha", they mean "every release is allowed to completely change everything". there is no expectation of compatibility between alpha releases, there is no release date for a stable version of them, and drivers that implement the 1.0 traits are rare
<re_irc>
<hartan> 9names: Thanks for sharing. I'm aware about the implications for the APIs. My issue is that my uC HAL implements alpha.8 (partially atm but I want to change that), and my target library implements alpha.7 (which I'll likely change, too), so I'm in a pretty unlucky situation.
<re_irc>
<9names (@9names:matrix.org)> unlucky indeed. i hope the porting effort goes smoothly!
<re_irc>
<hartan> 9names: Thanks, so do I. Otherwise I'll be sure to keep you updated with lots of pesky questions. :)
<re_irc>
<9names (@9names:matrix.org)> that pr isn't mine, it's henrik_alser's. and dirbaio is way more likely to answer (and have good advice) than I am, but if you ask here i'm sure someone will help out
<re_irc>
<jannic> hartan: I'm sure any feedback is welcome. Those alpha releases are little value if nobody tries them and reports the results. If they are difficult to use or the documentation is lacking, that should be changed.
<re_irc>
<jannic> +of
<re_irc>
<hartan> I've got a question about the "SpiBus", "SpiBusWrite" and "SpiBusRead" traits: Should I implement all of these on the same type (if my hardware has that capability), or should I prefer to implement them on separate custom types each?
<re_irc>
Because I assume that anything with "SpiBus" can be used as "SpiBusWrite" and "SpiBusRead" by setting the respective buffer to zero length. Or am I missing something here?
<re_irc>
<jannic> I don't think there is a need for separate types, or do you see any advantage I'm missing? If you can implement them on the same type, just do so.
<re_irc>
<henrikssn> Wow, just switched from Rust integration in VSCode to rust-analyzer. Why didn't I know about this earlier...
<re_irc>
<henrikssn> It's day and night
<re_irc>
<henrik_alser> hartan: all on the same struct!
<re_irc>
<hartan> henrik_alser: Uhm, that code is pretty complex for my current understanding of rust. I'll see what I can do with it, thanks!
<re_irc>
<henrik_alser> hartan: Ahh, just ask if you have any specifics :)
<re_irc>
<yruama_lairba> hi, i'd like to discuss about the 'I2s' mode of stm32 spi
<re_irc>
<James Munns> (might be better in the stm-rs channel)
<re_irc>
<yruama_lairba> it's discussion is about HAL design choice :)
<re_irc>
<yruama_lairba> * this
<re_irc>
<yruama_lairba> i manage to have one HAL struct to support all I2S mode ( philips, Msb, Lsb, Pcm)
GenTooMan has joined #rust-embedded
<re_irc>
<yruama_lairba> however, while same code is applicable, PCM mode have a subtle different behaviors so i wonder if i would be better to have another structure for PCM
<re_irc>
<yruama_lairba> those subtle difference confused me during test
<re_irc>
<hartan> henrik_alser: Okay, if you offer it so kindly:
<re_irc>
- What is "unborrow!"? I see it resolves to some "unborrow()" method, but where does that come from?
<re_irc>
- How does rust know whether e.g. "SpiBusWrite" is implemented for "Spim"? It can hardly exist when there's no "mosi". Do you make a dynamic check and if not where is the type hidden that ensures this?
GenTooMan has quit [Excess Flood]
GenTooMan has joined #rust-embedded
<re_irc>
<henrik_alser> hartan: ahh, i meant specifically to link to the part of the code where the e-hal impls live, the unborrow stuff is internal embassy related
<re_irc>
<dirbaio> > What is unborrow!?
<re_irc>
it allows creating the driver passing either "T" or "&mut T". The second is useful if you want to use the SPI temporarily, so you can drop it and not lose the peripheral singletons so you can create it again later. Most other HALs allow just "T".
<re_irc>
> How does rust know whether e.g. SpiBusWrite is implemented for Spim?
<re_irc>
currently you can still write on a rxonly SPI, it'll just do nothing (just toggle SCK). fixing this would require a "Mode" generic param, I'm not sure if it's worth it.
<re_irc>
<henrik_alser> I guess i misunderstood the original question, i meant you should impl all of them for a struct that can do all of them
<re_irc>
<dirbaio> ifi you want embedded-hal 1.0 impls for esp32 the easiest is probably taking the existing esp-hal/esp-idf-hal and add them, though
<re_irc>
<hartan> henrik_alser: dirbaio: Right, okay. So I take it then that I implement some SPI struct that has "sck" but "Option<mosi/miso>" like you used it, and then derive all the e-hal SPI impls I can on that one. Also I understand that to prevent "SpiBusWrite" to be implemented on an SPI that doesn't have a "mosi" I would need a generic parameter that defines the "mode" (which is pretty much its own type then, right?). So it's...
<re_irc>
... probably easiest I implement all of them and then, as you said, turn a write without a "mosi" into a noop. Good.
<re_irc>
<dirbaio> that's one way to do it, the one embassy picked
<re_irc>
<henrik_alser> You could also have different structs for the different variants
<re_irc>
<dirbaio> embedded-hal only mandates how the "final" API looks, but there's still lots of design choice left to the HAL author
<re_irc>
<hartan> dirbaio: Ideally that's what I'll do, if the knots in my head start untying.
<re_irc>
<hartan> henrik_alser: Didn't you state above that I should prefer to implement all traits on the same struct?
<re_irc>
<hartan> Anyway, very instructive discussion so far, thanks everyone!
<re_irc>
<dirbaio> embedded-hal mandates if a struct impls SpiBus, it must also impl SpiBusRead/SpiBusWrite. See here
<re_irc>
<dirbaio> this is because if it can do bidirectional transfers ("SpiBus") then it _surely_ can only read, or only write as well
<re_irc>
<dirbaio> BUT
<re_irc>
<dirbaio> there's three separate traits to still support the case of an SPI that can only read, or can only write
<re_irc>
<hartan> dirbaio: Yes, about that. I'm wondering whether it would suffice to only implement "SpiBus", and then "mock" the read-only and write-only parts by setting the respective buffers in the call to "transfer" to zero length. Should work, right?
rardiol has joined #rust-embedded
<re_irc>
<dirbaio> so, as a HAL author you have a few choices on how to lay things out.
<re_irc>
1. don't support readonly/writeonly at all. "struct Spi", requires "sck, mosi, miso", impls "SpiBus + SpiBusRead + SpiBusWrite"
<re_irc>
2. support readonly/writeonly with separate structs:
<re_irc>
<dirbaio> all these are "OK" choices, all comply with the embedded-hal trait requirements just fine (arguably "4" doesn't because the traits might not work if you haven't supplied the pins, but the added simplicity might be worth it)
<re_irc>
<dirbaio> so it's on you as a HAL author to pick, according to your taste :)
<re_irc>
<adamgreig> or 5, don't require pins to construct Spi, support rw+ro+wo?
<re_irc>
<jannic> Also, you can't really avoid the limitations of case 4 from software: even with the other options, the mosi pin might not be connected to anything.
rardiol has quit [Ping timeout: 260 seconds]
<re_irc>
<dirbaio> > then "mock" the read-only and write-only parts by setting the respective buffers in the call to transfer to zero length
<re_irc>
should work yup. depending on the implemntation, specific read/write impls might allow making it faster. for example because you can skip setting up the DMA channel in the unused direction
<re_irc>
<jessebraham> (We do not currently have DMA support in "esp-hal" so it can be ignored for now)
<re_irc>
<dirbaio> but if you're fine with the (small) overhead, implementing read/write on top of transfer is a good choice
<re_irc>
<dirbaio> simplifies the code
<re_irc>
<hartan> dirbaio: Neat, thanks! As you may have guessed I'm very inexperienced with that sort of thing, and having something like this in the docs would have saved me a lot of wondering about how possibly to approach this.
<re_irc>
<henrik_alser> hartan: Yes sorry i meant i misunderstood the original question, i meant if you had one that could do all of them you should impl all of them for that struct
<re_irc>
<dirbaio> adamgreig: but but but... muh generics, muh compiletime safety
<re_irc>
<dirbaio> 😜
<re_irc>
<dirbaio> (jk). yeah that's another choice
<re_irc>
<dirbaio> * yet another valid choice HALs can make!
<re_irc>
<firefrommoonlight> My pearls!
rardiol has joined #rust-embedded
<re_irc>
<almindor> in 310x we did sort of #3 with Spi<PINS> where PINS are a separate trait that exists for combinations of (SCK, MOSI, MISO) etc. and then you have subtraits for writeonly and readonly combination pins (as well as CS and CSless)
<re_irc>
<almindor> so you then prep your pins into the tuple and use that to init the SPI, e.g. say "(SCK, MOSI, ())" for write only
<re_irc>
<dirbaio> that works if the pin types are part of the Spi generic params
<re_irc>
<dirbaio> which is something I tried to avoid in embassy
<re_irc>
<dirbaio> so you don't get horribly long types like "Spi<'a, Spi4, (Pin<'A', 9, Output<PushPull>>, Pin<'A', 10, Output<PushPull>>, Pin<'A', 11, Input<Floating>>)>" :D
<re_irc>
<almindor> Sure it's very verbose. I do think embedded rust is generally overabstracted
<re_irc>
<burrbull> dirbaio: Let's stop manipulate. You never write something like this in real code. "Pin<'A', 9, Output<PushPull>>" can be written as "PA9<Output>", etc.
<re_irc>
<dirbaio> that's what rust-analyzer suggests as a type if you write "let _ = ...." to copypaste it
<re_irc>
<dirbaio> even if there's type aliases that allow you to write shorter types _if you know the type aliases exist_, having long types is bad for usability
<re_irc>
<dirbaio> in compiler error messages also, the type aliases won't show up there
<re_irc>
<dirbaio> and "Spi<'a, Spi4, (PA9<Output>, PA10<Output>, PA11<Input>)>" is still longer than "Spi<'a, Spi4>"
<re_irc>
<dirbaio> that's what rust-analyzer suggests as a type if you write "let x: () = ...." to copypaste it
<re_irc>
<dirbaio> and has other problems, like, you can't pick different pins at runtime based on a bootstrap GPIO or whatever because the type changes
<re_irc>
<dirbaio> I would appreciate if you assumed good faith btw, I'm not trying to "manipulate" anyone
<re_irc>
<Lachlan> I think rust will start substituting type aliases in error messages at some point
<re_irc>
<Lachlan> As a result of the alloc work
<re_irc>
<Lachlan> Not sure when tho
cr1901_ is now known as cr1901
explore has quit [Quit: Connection closed for inactivity]