ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to #rust-embedded:matrix.org and logged at https://libera.irclog.whitequark.org/rust-embedded, code of conduct at https://www.rust-lang.org/conduct.html
Advan[m] has joined #rust-embedded
<Advan[m]> Looking for a bit of help, I'm successfully running tinywasm on a pi pico and I'm trying to expose the gpio pins to the wasm module. All that works fine but the code to create instances of gpio pins doesn't seem to work. There's no panic but pin.set_high and pin.set_low don't seem to do anything when I call those methods against a pin 25 I unsafe created (should be the led pin). I think the way I'm declaring them is just incorrect
<Advan[m]> has anybody done anything like this before?
dinkelhacker has quit [Ping timeout: 248 seconds]
dkm has quit [Ping timeout: 248 seconds]
dinkelhacker has joined #rust-embedded
dkm has joined #rust-embedded
m5zs7k has quit [Ping timeout: 268 seconds]
m5zs7k has joined #rust-embedded
m5zs7k has quit [Ping timeout: 248 seconds]
m5zs7k has joined #rust-embedded
Socke has quit [Ping timeout: 268 seconds]
Socke has joined #rust-embedded
thejpster[m] has quit [Quit: Idle timeout reached: 172800s]
thejpster[m] has joined #rust-embedded
<thejpster[m]> The point of the pin types in the HAL is that owning a value of a given type proves that the hardware is in the correct state. If you unsafely conjure values, that’s no longer true.
<thejpster[m]> It might be worth reading the RP2040 datasheet and looking at how the SIO peripheral handles GPIO with its input register, output register and output enable registers.
dne has quit [Remote host closed the connection]
dne has joined #rust-embedded
jakzale has quit [Remote host closed the connection]
<thejpster[m]> congrats to probe.rs on the 0.27 release with RP2350 / ADIv6 support, and thank you to everyone who helped make that happen.
<thejpster[m]> including the mysterious "osdyne.com" who apparently sponsored the work
ryan-summers[m] has joined #rust-embedded
<ryan-summers[m]> I'm now very interested in hooking in to the risc-v core debug infra and seeing if we can make it tick. Especially given all the arm licensing drama lately
jakzale has joined #rust-embedded
dirbaio[m] has joined #rust-embedded
<dirbaio[m]> does anyone know how to make a cortex-m-rt-based project run from RAM?
<dirbaio[m]> ie make mcu boot from flash at usual, but very first thing it does is copy everything to RAM (text, rodata, data, bss) and then switch to running exclusively from RAM
<ryan-summers[m]> dirbaio[m]: Stabilizer does this by marking specific link functions since we have _some_ functions that are RAMFUNCs. See https://github.com/quartiq/stabilizer/blob/main/src/bin/dual-iir.rs#L347. But the general idea is that you have to manually manage the loading of flash -> RAM on startup before jumping into RAM execution
<ryan-summers[m]> We manually load the section using linker symbols on startup here: https://github.com/quartiq/stabilizer/blob/main/src/hardware/setup.rs#L152
<dirbaio[m]> I see
<dirbaio[m]> in this case I want everything on RAM though. the whole .text
<ryan-summers[m]> Yeah but you still will need some small bootloader that handles the copy from flash -> RAM, unless the probe does that
<dirbaio[m]> (use case is to allow the binary can erase itself from flash and replace itself with something else)
<ryan-summers[m]> In that case, just specify your FLASH section as the RAM memory region in the linker file and let the debug probe do it?
<dirbaio[m]> has to work with regular boot, no debug probe :(
<dirbaio[m]> s/can/to/
<ryan-summers[m]> Hmm I think it's problematic to have a binary that works in both flash and RAM, since you'd have to use only relative addressing?
<ryan-summers[m]> But if you had purely relative addressing, you could theoretically have a binary that doesn't care where it's executed
<ryan-summers[m]> If you're thinking of a small bootloader that runs in RAM to update firmware, what is often done is to write a small standalone RAM-based loader utility, or even just a function chain that exists in RAM for the temporary reprogramming process
Mathias[m] has joined #rust-embedded
<Mathias[m]> <thejpster[m]> "Can you all just stop writing..." <- Are they really the same? I have looked at pl011 drivers in the past, found a dozen different that fell roughly into 3-4 « styles » (IMHO). Some of the differences might be due to personal preferences, some might be due to differing use-cases (or priorities). But what concerns me is that it’s hard to understand what the best practices are or should be. I hate the term, but
<Mathias[m]> is there a way to tell which on is the « best ». Maybe some guidance from this forum could help?
<Mathias[m]> s/on/one/
JamesMunns[m] has joined #rust-embedded
<JamesMunns[m]> @dirbaio when I've done that, yeah, I write two projects:
<JamesMunns[m]> * a RAM only image
<JamesMunns[m]> * A flash image that include_bytes the first, copies it to RAM, then jumps to it as a bootloader
<dirbaio[m]> 💀
<JamesMunns[m]> I have a project... somewhere that does that? But I don't think you'd get more useful info than that 😃
<JamesMunns[m]> For the RAM only image, yeah, I put the FLASH region in a RAM section, which is where the loader puts the RAM into
<dirbaio[m]> I was hoping it'd be possible to do it with just 1 binary lol
<JamesMunns[m]> probably not without position independent code
<ryan-summers[m]> Are you trying to avoid bootloaders? Why on earth would you do that?
<ryan-summers[m]> I say while having written 3 different bootloaders in the last week :'(
<JamesMunns[m]> I've written it for a tool that is loaded using an existing bootloader, loads the payload into ram, then either writes a new bootloader directly, or makes a USB/whatever connection to act as RAMloader
<JamesMunns[m]> I wanted to swap the adafruit bootloader to my bootloader on nrf52840 devices :p
<dirbaio[m]> ryan-summers[m]: this *is* for a bootloader, we want the bootloader to update itself
<diondokter[m]> dirbaio[m]: Maybe if you write the bootloader part as asm? Then it can stand fully on its own and you can make sure it does't link to anything.
<diondokter[m]> Otherwise you'll always have the issue that the bootloader and application share the same e.g. memcpy. And where is that memcpy?
<dirbaio[m]> the bootloader update will not be power-fail-safe but it's okay, because it should be very rare
<dirbaio[m]> the bootloader can update the main app in a power-fail-safe way
<dirbaio[m]> (it's a long story 🫠)
<thejpster[m]> oh no, a "bootloader upgrader". I've have written these. They're scary.
<JamesMunns[m]> <JamesMunns[m]> "I have a project... somewhere..." <- It's here, btw: https://github.com/jamesmunns/soupstone/blob/main/experiments/xiao-init-stage-minus-1/src/main.rs
<thejpster[m]> basically no, I don't think you have a program that is linked to run in one place where you then switch where it runs from at run-time. I thii
<ryan-summers[m]> Yeah I was going to say, this is "There be dragons" territory. Every project I've been on has decided the risk was too high (med devices)
<thejpster[m]> think you need to programs jammed together - one that puts the code into RAM and the code that runs from RAM
<thejpster[m]> or use an RP2350 where "the code thing that puts the code in RAM" is already in ROM for you
Kaspar[m] has joined #rust-embedded
<Kaspar[m]> Or, to levels of bootloaders.
<Kaspar[m]> s/to/two/
<ryan-summers[m]> That sounds like BIOS with extra steps
Koen[m] has joined #rust-embedded
<Koen[m]> At least we don't have to start our microcontroller in 16 bit mode
wbezs[m] has joined #rust-embedded
<wbezs[m]> If you see a embedded system with AI sticker on it, just take a heavy hammer in the hand.
<danielb[m]> that's some solid reasoning there LOL
danielb[m] has joined #rust-embedded
<wbezs[m]> danielb[m]: european hallucinatory agent xD
<danielb[m]> wbezs[m]: you can give it to a class 5th graders as homework and see how many errors they can find in it, so it has _some_ value 😅
<thejpster[m]> I don't understand the problem. You asked a random word generator to generate some random words and it did exactly that.
<thejpster[m]> Today I am banging up against the volatile_cell problem and I can't find any good solutions.
<thejpster[m]> I really feel like we should have solved this by now.
<thejpster[m]> "Write an SVD file for a chip with an 8000 page datasheet" is not a solution.
<thejpster[m]> "just ignore the problem and make references to MMIO structures" is also not a solution (and apparently what using tock_registers for MMIO requires)
<thejpster[m]> I just want #[derive(Mmio)] struct Uart { .... } to do all the things for me.
<thejpster[m]> and by things I mean give me read, write and modify methods for every field in the structure.
<dirbaio[m]> that's sort of what device-driver is
GrantM11235[m] has joined #rust-embedded
<GrantM11235[m]> That sounds like it would be a pretty easy derive macro tbh (famous last words)
<dirbaio[m]> it's not oriented for MMIO though but it could be made
<JamesMunns[m]> does chiptool (or svd2rust) have any reasonable IR that could be used to write from-scratch inputs?
<dirbaio[m]> is writing the registers by hand sucks, even if you're writing nice rust instead of svd xml
<dirbaio[m]> * the thing is writing
<thejpster[m]> I can transliterate from the manfacturer's C header files quickly enough
<JamesMunns[m]> ah, yeah, I'd be suggesting making a nice crate interface that could emit chiptool yaml, if that's a stable enough target
<dirbaio[m]> and if you're autmating it, it's easier to get it to write yaml/json than rust
<thejpster[m]> https://crates.io/search?q=chiptool doesn't turn up the crate itself
<JamesMunns[m]> yeah, I don't think it has a crate interface, just the bin tool: https://github.com/embassy-rs/chiptool
<dirbaio[m]> it's not on crates-io
<JamesMunns[m]> It might be interesting to pull out the chiptool yaml type defs into a separate crate so you can include that
<dirbaio[m]> this has serde-compatible structs for reading/writing the IR https://github.com/embassy-rs/chiptool/blob/main/src/ir.rs
<dirbaio[m]> anyway if you're going to do it i'd recommend writing it in python, not rust
<dirbaio[m]> python is much quicker for one-off data scraping+munging like this
<thejpster[m]> where is the chiptool YAML syntax defined?
<dirbaio[m]> that ir.rs file
<JamesMunns[m]> how do we smash together bindgen and chiptool to read in C structs and spit out chiptool yaml? :p
<dirbaio[m]> JamesMunns[m]: I don't think it can be done in a generic way, C headers are usually unstructured define-soup
<JamesMunns[m]> yeah, I believe it
<thejpster[m]> it would be a hard sell to my clients in a training course, if it doesn't have well defined releases
<thejpster[m]> but I can give it a go
<dirbaio[m]> you can also use svd2rust
<dirbaio[m]> like, the only advantage of chiptool is the yaml is a bit more tolerable than SVD XMLs
<dirbaio[m]> * of chiptool for this use case is the
<JamesMunns[m]> does svd2rust do the Right Thing wrt volatile access these days?
<JamesMunns[m]> I know the function call got added, does that do the right "use a ptr not a ref" thing?
<dirbaio[m]> no, it still uses vcell :P
<JamesMunns[m]> womp womp
<dirbaio[m]> ah well yeah this would be another advantage of chiptool then :D
<dirbaio[m]> but it's more theoretical, vcell works okay in practice 🤷
<thejpster[m]> > "Write an SVD file for a chip with an 8000 page datasheet" is not a solution.
<thejpster[m]> I refuse to believe the correct solution for people bringing up a chip is "write an SVD file"
<JamesMunns[m]> thejpster[m]: It's the best volunteer solution we've come up with so far.
<thejpster[m]> although I accept that at least the SVD format has an XSD you can check against ;)
<JamesMunns[m]> Seems not many people are interested in supporting Quirky vendors who don't ship SVDs in their spare time :p
<JamesMunns[m]> even the risc-v folks have ended up generating pseudo svd files for the path of least resistance
<dirbaio[m]> yeah there's literally nothing you can do if the vendor doesn't publish machine-readable descriptions of the regs
<JamesMunns[m]> scrape pdfs, scrape headers, all of which are fragile af
<thejpster[m]> disagree - you can design a system to allow a human to write the descriptions of registers
<JamesMunns[m]> I don't think anybody is stopping that from being done. but nobody has done it yet either.
<dirbaio[m]> I think nobody has done it because after you do it you have to write the registers manually which nobody wants to do :D
<JamesMunns[m]> as mentioned, device-driver has some pretty cool syntax for that, if it is desirable
<thejpster[m]> reading the PDF is not my issue. I can read the PDF. I can read the C header. What I apparently can't do is tell the Rust compiler that I have a structure which is in I/O memory and it should let me access its fields without tripping up LLVM into making it dereferecnable
<GrantM11235[m]> That's what pointers are for
<thejpster[m]> you can't access the field of a structure given only a pointer to the structure
<JamesMunns[m]> because in llvm, ACCESS is volatile, TYPES are not.
<dirbaio[m]> yes if you codegen
<dirbaio[m]> the "make a structure overlaying the mmio regs" thing is a C-ism that shouldn't exist in rust IMO
<JamesMunns[m]> thejpster[m]: What do you mean? you super can with addr_of(_mut)
<thejpster[m]> OK, you can't do it with the normal field access syntax.
<JamesMunns[m]> we've just been giving out references to structs and deref'ing them as if they were normal structs.
<JamesMunns[m]> i'm in favor of Gankra's proposed `~>` syntax :D
<dirbaio[m]> there's no advantage in "struct overlapping mmio" vs "struct wrapping pointer, methods doing pointer math"
<JamesMunns[m]> ah it's just `~` not `~>`.
<thejpster[m]> dirbaio[m]: there is if you're looking at a C structure and you want a Rust one
<dirbaio[m]> why?
<dirbaio[m]> "that's the way you do it in C" is not an advantage
<JamesMunns[m]> Also, just checking, do you WANT to discuss this @thejpster, or just venting?
<JamesMunns[m]> (or really, do you WANT suggestions)
<thejpster[m]> no I really do have a chip with an 8000 page datasheet I need to program
<thejpster[m]> and almost every customer I have will have the same problem
<thejpster[m]> so if Rust is supposed to work for these systems, a solution needs to exist. What I'm hearing is that I'm holding it wrong, and no-one should be expected to do it for free, and I should just have an SVD file anyway, or learn YAML for a format that isn't documented and run it through a tool that doesn't have stable releases.
<thejpster[m]> if the embedded devices working group isn't offering solutions to problems like this, then ... what is the working group for?
<JamesMunns[m]> what do you want?
<dirbaio[m]> the WG has a pretty solid answer which is svd2rust
<thejpster[m]> what do I want? I would like the WG to accept that 'write an SVD / YAML file' isn't going to work for a lot of people.
<GrantM11235[m]> Well what do you want to write?
<JamesMunns[m]> So what do you think will work?
<dirbaio[m]> SVD is the industry-wide de-facto standard, Even super obscure chinese MCU vendors publish SVDs, even riscv vendors lately.
<dirbaio[m]> svd2rust has worked fine for a wide array of MCUs
<thejpster[m]> I don't have an MCU
<thejpster[m]> I have an automotive SoC with eight Cortex-R52 cores and seven Cortex-M33 cores.
<diondokter[m]> <JamesMunns[m]> "as mentioned, device-driver..." <- I guess I should add alternative generation so it doesn't expect reads and writes to be fallible. That's really the only thing stopping it from being useful for mmio.
<diondokter[m]> The interface would be different from PACs though. Everything is made to be around a driver instance. But maybe that can be mended too
berkus[m] has joined #rust-embedded
<berkus[m]> thejpster[m]: Do they have SVDs?
<dirbaio[m]> if Ferrous wants to offer support to their paying customers for crappier cortex-r vendors that don't publish SVDs then Ferrous should take on that work
<dirbaio[m]> either adapt device-driver, write your own derive macro from scratch, or fork chiptool and do stable releases of it if that's the only blocker
i509vcb[m] has joined #rust-embedded
<i509vcb[m]> I thought that Sony's Spresense parts were already nuts with 6 M4F cores, but the automotive soc is a whole different level
<i509vcb[m]> s/the/that/
<dirbaio[m]> instead of asking others to do that work for you for free
<dirbaio[m]> there's plenty of possible solutions, it's just nobody has developed them because their needs are different to yours
<diondokter[m]> <diondokter[m]> "I guess I should add alternative..." <- > <@diondokter:matrix.org> I guess I should add alternative generation so it doesn't expect reads and writes to be fallible. That's really the only... (full message at <https://catircservices.org/_irc/v1/media/download/Ad9-SaiUHslVuLxMcmi5sJ-d99oA0VoHd4Z5NN1WAVqIln-fZdIaRk2S1UArTe5izLgbqltLMJADhsU7d7-OoHS_8AAAAAAAAGNhdGlyY3NlcnZpY2VzLm9yZy9BclZVcGdCbE5RV3ZYVlV5YlFNUEFOR2Q>)
<JamesMunns[m]> I really wish we had a better way of funding "the commons" for embedded rust dev. I really do.
<diondokter[m]> Also pretty fun, I know two Microsoft embedded Rust drivers are using 'device-driver' 😁
<dirbaio[m]> best way to "fund" it is to contribute work
n_vl[m] has joined #rust-embedded
<n_vl[m]> Honestly, ferrocene has done a lot more than most automotive brands. Especially considering the investment size in their respective „ecosystems“ and their relative returns. A small company filled with passionate individuals can still expect people to pay them if their passion doesn’t burn quite fast enough for their potential customers needs..
<n_vl[m]> Sorry to jump in here but from an outsider this looks like a lot of demanding of work to be done for free for which there was never a promise that someone did it for you
<thejpster[m]> I have no problem doing the work, or making it open source (points at all the other things we published).
<thejpster[m]> What I would like is some like minded people to accept that there's an issue, propose possible solutions, and co-ordinate efforts.
<thejpster[m]> diondokter: your docs for device-driver are amazing, by the way.
<i509vcb[m]> Unfortunately I have tried parsing pdf datasheets and it is incredibly hard. Even if you had a 99.9% accuracy, for an 8000 page datasheet you would have at least 8 pages with errors
<diondokter[m]> Thanks 😃
<JamesMunns[m]> I don't think you need anyone's approval if you're planning on doing the lift!
<diondokter[m]> I should create a json schema I guess
<JamesMunns[m]> I think it WOULD be good to have more ways to get devices supported!
<JamesMunns[m]> If more people get involved, like if TweedeGolf needs features for their customers, and you need a home for shared maintenance, I think the wg could be a good potential home for that!
<JamesMunns[m]> But the WG has always been more successful "give a home for people doing things", rather than "tackle a new, specific thing".
<JamesMunns[m]> * more successful at "give a
<dirbaio[m]> I do agree it's an issue! it's a giant pain to have to scrape register definitions. I've had to do it for i2c devices and it sucks.
<dirbaio[m]> It's just that according to my view of what the solutions would look like, it's mostly covered by existing tools like device-driver and chiptool
<dirbaio[m]> * and chiptool already
<JamesMunns[m]> That's part of why I asked what you were looking for JP - if this was a comms problem, and you were looking for input on something to build, I wanted to make that clear! Rather than just saying the current state of things wasn't good enough.
<dirbaio[m]> for example I personally wouldn't invest effort myself in some #[derive(Mmio)] because I think "struct overlapping mmio regs" is not the best way to do MMIO in rust
dngrs[m] has joined #rust-embedded
<dngrs[m]> You could always ask an LLM to do it. It will be hilariously wrong but on the bright side you'll get some sweet VC money which you can then use to pay people for developing the actual solution 😬
<danielb[m]> "Here is a die shot, give me the rust PAC based on it"
<i509vcb[m]> Maybe a little unrelated, how are vendors writing these SVD files? Some script to pass over a bunch of systemverilog or paying some poor soul to write out XML by hand?
bogdan[m] has joined #rust-embedded
<bogdan[m]> <dirbaio[m]> "SVD is the industry-wide de-..." <- Oh, I see you haven't met the Automotive Industry :)
<dirbaio[m]> oh yeah I can definitely believe it's crappy
<bogdan[m]> very ... conservative, not necessarily crappy. some parts are really crappy, though.
<i509vcb[m]> I imagine it gets a bit more annoying when some auto makers are then also taping out custom silicon
<bogdan[m]> ended up writing a parser to extract register definitions from some (proprietary) IDE just to be able to create a pac
<bogdan[m]> ... and it was still wrong
<i509vcb[m]> Parsing IDE metadata is what made my MSPM0 HAL even practical to work on
<diondokter[m]> Or we all just come to our senses and don't buy chips without machine-readable datasheets. Then we can just let the market do its thing
<JamesMunns[m]> IIRC SVDs specifically were made for IDEs and debuggers
<JamesMunns[m]> Using it for codegen was a "happy accident"
<JamesMunns[m]> but also probably why there originally wasn't much QA on it
<dirbaio[m]> SVD also has fields for "C struct field" etc, so seems it's also sort of intended for codegen
<dirbaio[m]> or maybe it's a later addition
<diondokter[m]> I still don't get how so many SVDs are so bad too. Like, they have the HDL. Just generate the SVD from that! It doesn't need to be from an in parallel, manually created, excel sheet.
<i509vcb[m]> Bad SVDs are a tale as old as time unfortunately. I've written like 6 chiptool transforms because of it
<dirbaio[m]> you don't simply generate svd from hdl,lol
<dirbaio[m]> * from hdl, lol
<JamesMunns[m]> dirbaio[m]: you totally SHOULD, or at least from the same source. I know it doesn't happen in practice tho lol
<diondokter[m]> Ok, to be fair, I'm an HDL noob. But it seems to me the registers are defined there somehow
<diondokter[m]> Probably want to have some out-of-band metadata too
<diondokter[m]> * metadata too for names and docs
<Koen[m]> Probably generate that bit of the HDL from the SVD files
<diondokter[m]> That's ok too. As long as they're in sync
vollbrecht[m] has joined #rust-embedded
<vollbrecht[m]> They don't want to accidentally leak the secret registers present in their HDL to SVD 😂
<i509vcb[m]> About that, TI leaves a ton of secret registers in their MSPM0 SVDs
<i509vcb[m]> Loads of trim and management registers
<danielb[m]> <vollbrecht[m]> "They don't want to accidentally..." <- you laugh
wassasin[m] has joined #rust-embedded
<wassasin[m]> <diondokter[m]> "Or we all just come to our..." <- "just use our C driver"
<dirbaio[m]> something something nrf7002
<diondokter[m]> wassasin[m]: "...that depends on our whole ecosystem"
<danielb[m]> better than "here is a blob, good luck"
<dirbaio[m]> "... and has shit code quality because it's been through 2 acquisitions"
<diondokter[m]> danielb[m]: Honestly... We made libmodem work and we didn't with the nrf7002
<wassasin[m]> Will be trying out embassy-net-esp-hosted soon, ESP32-C6 is way cheaper than NRF7002 too
<wassasin[m]> But yeah, I've been implementing a whole bunch of device-driver crates over the past few months, and most of the work is transcribing PDFs into YAML files like a monk
adamgreig[m] has joined #rust-embedded
<adamgreig[m]> hi @room, meeting time again! agenda is https://github.com/rust-embedded/wg/discussions/816, please add anything you'd like to announce or discuss and we'll start in a few mins :)
<wassasin[m]> diondokter: maybe make device-driver support in ngscopeclient to view device state just by looking at the I2C or SPI bus
<i509vcb[m]> <diondokter[m]> "Honestly... We made libmodem..." <- I still have an interesting in making it work, but it's certainly at the back of that queue
<dirbaio[m]> can't blame you lol 🥲
<i509vcb[m]> I assume I can just throw in a comment on that discussion page for something (or here)
<JamesMunns[m]> I think usually informal plugs here, "to be discussed" on the issue
<JamesMunns[m]> (or I've been doing it wrong for a while lol)
<i509vcb[m]> Basically I want to mention this issue i opened about a week ago about async variants digital traits
<i509vcb[m]> * async variants of the digital traits
<adamgreig[m]> ok, let's begin
<adamgreig[m]> James Munns: wanna mention embedded world?
<JamesMunns[m]> Sure!
<JamesMunns[m]> There's a couple of us that will definitely be there, I made a discussion topic so people could sound off: https://github.com/rust-embedded/wg/discussions/813
<JamesMunns[m]> Just generally excited to see all the Rust folks at Embedded world! I'll be there with @diondokter and @wassasin as a shared booth, I know @thejpster will be there with Ferrous
<JamesMunns[m]> Oooh, Espressif folks as well!
<JamesMunns[m]> Feel free to add yourself (don't have to be WG members) if you'll be there too or want to meet up with other Rust folks :)
<adamgreig[m]> cool! other reminder is that Rust Week is happening in May (12-17th) in Utrecht, along with the rust all-hands there's an embedded unconf for us to meet up and chat and work on/discuss embedded stuff, if you're interested in coming to the unconf please let me know so I can put you on the guest list :)
<adamgreig[m]> details are here: https://rustweek.org/unconf/
<adamgreig[m]> you don't have to be a wg member, either
<adamgreig[m]> thejpster: sorry, I'll do the arm team vote issue now, totally slipped my mind last week
<adamgreig[m]> James Munns, website update?
<JamesMunns[m]> Yep! They are making some changes to rust-lang.org
<JamesMunns[m]> Basically the green box on this page is going away: https://www.rust-lang.org/governance
<JamesMunns[m]> And since we have added some teams to the launching pad, like the project goals and internship teams, there's gunna be a new page that lists ALL the launching pad teams
<JamesMunns[m]> Current wg page links will continue working
<JamesMunns[m]> Just wanted to mention it because I lost the notification when originally pinged, and it looks like it's moving forward. If there are any concerns, lemme know or raise them up in the issue/pr
<adamgreig[m]> so the wg page remains, but it's linked to from a new launchpad page?
<JamesMunns[m]> yep!
<JamesMunns[m]> (as far as I know!)
Noah[m] has joined #rust-embedded
<Noah[m]> Ah nice :) Would have been a shame to loose this :)
<JamesMunns[m]> Yep, basically like the subteams for infra, for example: https://www.rust-lang.org/governance/teams/infra
<JamesMunns[m]> so all the wgs will appear as subteams of the launching pad top level team
<JamesMunns[m]> (I'll have to check how the new version handles subteams of subteams 😃)
<adamgreig[m]> thanks for the update :)
therealprof[m] has joined #rust-embedded
<therealprof[m]> Turtles all the way down...
<adamgreig[m]> i509vcb: want to go ahead and introduce your issue?
<i509vcb[m]> Sure, so currently there are only blocking ways to drive the GPIO pins via the embedded-hal traits. This works on hardware since mmio for GPIO registers is effectively immediate.
<i509vcb[m]> However I've been working on a bit of firmware to turn an MCU into an IO expander and that paradigm doesn't work given that the GPIO access might be behind USB, an i2c transaction or something else (which may take time).
<i509vcb[m]> Adding a new trait is easy enough, but most crates currently depend on the blocking traits and there isn't really a nice way to say `T: blocking digital or async digital`
<i509vcb[m]> Link for a little more context: https://github.com/rust-embedded/embedded-hal/issues/647
<adamgreig[m]> right, being generic over async is a Whole Thing
<i509vcb[m]> There are also IO expander parts which exist, which can't be blocking either
<wassasin[m]> Yes, so currently you cannot use those gpio expander pins in existing driver implementations
<JamesMunns[m]> If we retained the error type for remote gpios, might as well add a trait for async control of remote gpios as well :D
<adamgreig[m]> we do talk a lot about how digital is fallible because it might return an error if it's being used over an IO expander, so yea
<JamesMunns[m]> I don't think we want to be generic over either blocking or async, but adding an async pin io trait seems reasonable to me
<JamesMunns[m]> similar to blocking/async spi ops, for example.
<i509vcb[m]> Yeah being generic over either is probably something for the peripheral crates to do
<JamesMunns[m]> or just implementing both traits
<i509vcb[m]> (If desired of course)
<wassasin[m]> Classic 'instant' io trait pins can be trivially be made to also implement the async trait
bartmassey[m] has joined #rust-embedded
<bartmassey[m]> I don't understand nb or async very well. Could one do an async function for something that provides the nb interface?
<JamesMunns[m]> nb and async aren't generally compatible or translatable
<JamesMunns[m]> they achieve sort of the same thing, but in different ways
<JamesMunns[m]> nb doesn't coordinate with wakers, and doesn't have the ability to fully yield, so you sort of have to manually do that or just spin.
jannic[m] has joined #rust-embedded
<jannic[m]> A gpio driver which only writes to local mmio registers is probably one of the rare cases where being generic over sync/async would be trivial as there's really nothing to wait for and no additional error cases.
<i509vcb[m]> Yeah on hardware the async function would always be ready
<JamesMunns[m]> yeah, it's probably in most cases just call the blocking function and immediately return ready
<jannic[m]> Well at least as long as the async variant doesn't provide functions like wait_for_edge or similar.
<JamesMunns[m]> that's a separate trait
<JamesMunns[m]> (Wait)
<i509vcb[m]> Well wait_for_edge already exists on Wait
<JamesMunns[m]> Ah, I thought we were just talking about "get" and "set" methods
<i509vcb[m]> The issue is just for get and set
<i509vcb[m]> wait is already async and can handle the delay being a thing
<i509vcb[m]> I can write up a pull request, but I would like to get a MVP for the IO expander thing before committing to the traits being merged in case I forgot something
<dirbaio[m]> adding async gpio traits LGTM
<dirbaio[m]> my concern is most drivers will still use the blocking traits out of convenience
<dirbaio[m]> but there's little we can do about that
<GrantM11235[m]> I'm not sure that the benefit is worth the potential confusion
<dirbaio[m]> yeah that too
<jannic[m]> We could provide an adapter which implements the async trait by calling the sync one with the caveat "only use this if you know the sync implementation doesn't block for anything".
<dirbaio[m]> there's already this duplication for io, spi, i2c and people haven't reported confusion so far though
<GrantM11235[m]> You can already use IO expanders with the current traits, they just need to be blocking
<GrantM11235[m]> Just a week or two ago, someone was confused because they thought that a driver that uses async spi would also need to use async OutputPin
<dirbaio[m]> i'd argue it's more confusing that there's blocking+async spi but only blocking gpio though
<wassasin[m]> If we can impl the async pin trait for the classic pin by default it would be as easy to use, only possible generate confusion if you look at the type
<adamgreig[m]> and if you do have an i2c io expander, it kinda sucks to have to block on its pins.. though it's true that initially a lot of drivers you pass the pins to will just want the blocking one
<wassasin[m]> s/possible/possibly/
<n_vl[m]> Why would you need async Pin?
<n_vl[m]> Is there a case where toggling a Pin is incompatible with async?
<JamesMunns[m]> If your pin is exposed over a port expander that you talk to with async
<i509vcb[m]> This kind of gets into the possible race conditions if the transport for that request could require retransmission or get lost
<JamesMunns[m]> like over i2c or spi.
realroot[m]1 has quit [Quit: Idle timeout reached: 172800s]
<i509vcb[m]> Generally if you toggle gpio 1 and then gpio, you would expect that the blocking calls would toggle gpio 1 and the gpio 2
<GrantM11235[m]> It's not incompatible, its just not optimal
<i509vcb[m]> * then gpio 2, you
<i509vcb[m]> * Generally if you toggle gpio 1 and then gpio 2, you would expect that the blocking calls would toggle gpio 1 and then gpio 2
<jannic[m]> It may even be incompatible. What if your GPIO expander is behind a complex protocol stack (say an IP network) and you need your async executor to run to handle the network communication. If you did a blocking gpio access on such a pin, you'd get a deadlock.
<i509vcb[m]> I reference the case I mentioned if you try to bend the rules and secretly treat the pins as async under the hood, with the blocking call just defering some message later that is truly async
<dirbaio[m]> i509vcb[m]: impl wouldn't be allowed to return before it's confirmed the gpio is actually toggled
<adamgreig[m]> that's no different to anything else though. it should probably just return an error or wait, yea
<adamgreig[m]> same deal with async spi or whatever
<therealprof[m]> There's also the question how async GPIO would combine with other IO. Isn't the idea of multiple async things can happen at their own pace?
<adamgreig[m]> sure, but they happen in-order still
<adamgreig[m]> if you go "pin1.set_high().await; pin2.set_high().await" then pin 1 will go high before pin 2
<wassasin[m]> The user did decide to stick a GPIO expander on the PCB so they made peace with the fact that it's gonna take a while
<bogdan[m]> jannic[m]: Is that even a "Pin" anymore? Sorry, I've never used an IO expander. To me it seems like this should be a device driver. Calling it a GPIO Pin seems strange to me.
<adamgreig[m]> it's a pin because you want to pass it to other things that take a pin
<adamgreig[m]> for example, maybe you're using a gpio expander to provide 8 CS pins for a shared SPI bus
<adamgreig[m]> you need to give the OutputPin to your SPIBus to get the SpiDevice
<bogdan[m]> a, ok. thanks, that use case makes more sense
<therealprof[m]> adamgreig[m]: I was thinking more about async GPIO to assert CS, do SPI and then deassert CS.
<wassasin[m]> Yeah, that's an important point, not only drivers need to change to the new API, SPIDevice-impls need too
<dirbaio[m]> SpiDevice-over-Ethernet 🤪
<i509vcb[m]> One of the use case I have is implementing a keyboard matrix behind an IO expander, and blocking might not be ideal for that
<adamgreig[m]> therealprof: same deal, cs.set_low().await; spi.transfer().await; cs.set_high().await will still be all in order
<JamesMunns[m]> wassasin[m]: Yeah, but you could have impls that do that, it doesn't break anything currently
<i509vcb[m]> I would be using a 2nd MCU in the keyboard matrix case to act as an IO expander
<JamesMunns[m]> wassasin[m]: You take the pin in the constructor
<wassasin[m]> I too have both a GPIO Expander, and a driver that needs to use pins attached to it, and now I just hacked it in the API. For now that driver is closed source so no problem but it would block me putting it on crates.io eventually
<i509vcb[m]> dirbaio[m]: Funny enough my library for MCU as a IO expander would in theory allow for that
<therealprof[m]> adamgreig[m]: Interesting, I thought the point of async SPI was not having to await each step... Doesn't that effectively make it an blocking operation again?
<JamesMunns[m]> adamgreig[m]: it does, but you can multiplex OTHER tasks at the same time
<i509vcb[m]> Meme uses like bit banged i2c over remote gpio are probably not the most practical thing
<wassasin[m]> It's not blocking, the MCU can WFI during the await while it is waiting for the interrupt to be called
<JamesMunns[m]> adamgreig[m]: ONE task is sequential, multiple tasks are concurrent, or you can opt-in to multiplexing if you use select! or similar.
<JamesMunns[m]> ONE task is sequential, multiple tasks are concurrent, or you can opt-in to multiplexing if you use select or join or similar.
<jannic[m]> <dirbaio[m]> "SpiDevice-over-Ethernet 🤪" <- https://github.com/Disen-Shaw/EtherCAT_Slave_Demo
<JamesMunns[m]> <adamgreig[m]> "therealprof: same deal, cs...." <- (select says "run all these futures at the same time until ONE is done", join says "run all these futures at the same time until ALL of them are done, await says "run this one future until IT is done")
<wassasin[m]> And if all current futures are pending the executor could decide to WFI until an interrupt that wakes a waker
<dirbaio[m]> therealprof:
<dirbaio[m]> async by default runs things sequentially within the current task, but still lets *other tasks* proceed concurrently.
<dirbaio[m]> you can opt-in to doing multiple things concurrently within a single task with `join`, `select`, etc.
<dirbaio[m]> * therealprof:
<dirbaio[m]> async by default runs things sequentially within the current task, but still lets _other tasks_ proceed concurrently. Blocking would block all taks.s
<dirbaio[m]> you can opt-in to doing multiple things concurrently within a single task with `join`, `select`, etc.
<dirbaio[m]> * therealprof:
<dirbaio[m]> async by default runs things sequentially within the current task, but still lets _other tasks_ proceed concurrently. Blocking would block all tasks.
<dirbaio[m]> you can opt-in to doing multiple things concurrently within a single task with `join`, `select`, etc.
<therealprof[m]> dirbaio[m]: It's not entirely true that blocking would block all tasks... You can still run interrupt handlers while the MCU is doing blocking operations.
<dirbaio[m]> interrupt handlers are not tasks
<therealprof[m]> But I get your point.
<adamgreig[m]> so, i509vcb would you like to put a pr in to propose something?
<i509vcb[m]> I'll open a pull request to propose something yeah
<i509vcb[m]> Although I do want to write a test implementation (with a "IO expander") before merging it
<i509vcb[m]> Or if I'm lazy, grab a DIP package IO expander off mouser when I order in the next week some more stuff and perfboard test it
<wassasin[m]> I can also test it with my impl once you have a proposal
<adamgreig[m]> sounds good!
<i509vcb[m]> wassasin[m]: I'll keep that in mind, thanks for the offer
<JamesMunns[m]> I can write a gpio-over-usb expander too if you want 😃
<i509vcb[m]> Unfortunately my rp2040 is sitting and home and we have horizontal rain in college station so I'd prefer to wait until after class to avoid a roundtrip in the rain
<i509vcb[m]> s/and/at/
<i509vcb[m]> So I can try something later today and over the next day or two
<i509vcb[m]> At least it's nice and cool today rather than early winter broiling we get in Texas
<adamgreig[m]> cool, thanks everyone! that's all we have time for today. just as we finish, I opened https://github.com/rust-embedded/wg/pull/818 about the proposal for a new arm team
<adamgreig[m]> please leave any thoughts there :)
almindor[m] has quit [Quit: Idle timeout reached: 172800s]