<re_irc>
< (@almindor:matrix.org)> yeah, I guess easier would be to just make a "[u8; 6]" and copy byte by byte, perhaps keeping the buffer as an argument to be passed in and giving the size requirement somehow... i don't know :)
<re_irc>
< (@adamgreig:matrix.org)> what do you actually need to do here? for this sort of thing i'll usually either serialise the u16 to a new u8 array in the required byteorder (if different to platform order), or create a slice aliasing the same memory, and the latter maybe with a repr(c) struct containing several items
<re_irc>
< (@almindor:matrix.org)> I'm trying to abstract the DCS command set/params into a common abstracted type
<re_irc>
< (@adamgreig:matrix.org)> 6 bytes is like 1.5 pointers so it's probably not much worse than anything else you can do, storage-wise
<re_irc>
< (@almindor:matrix.org)> so instead of doing the C-like "write_command(spi-stuff, InstructionByte, &[u8-param slice])" you can do something like "SpecificInstruction::new().with_specific_arg(true).and_some_other_arg(5)" and in the end just get that [u8]
<re_irc>
< (@almindor:matrix.org)> note that each command is different size of params (0 to X, can be biggeR)
<re_irc>
< (@adamgreig:matrix.org)> i'd just have the builder finally return a suitably sized [u8; N] array then
<re_irc>
< (@adamgreig:matrix.org)> assuming the biggest is still on the order of like 32 bytes then it's unlikely to be an issue...
<re_irc>
< (@almindor:matrix.org)> how do I choose the size? let's say I cut off the "unlimited" cases, do I just return "[u8; MAX_KNOWN]" from each implementor?
conplan has joined #rust-embedded
<re_irc>
< (@adamgreig:matrix.org)> oh I see, so even SpecificInstruction will have different return size depending on which arguments you set?
<re_irc>
< (@almindor:matrix.org)> oh no, specificinstruction is always known
<re_irc>
< (@adamgreig:matrix.org)> if SpecificInstruction always returns 6 bytes, its builder can return [u8; 6]?
<re_irc>
< (@adamgreig:matrix.org)> if SpecificInstruction::new().with_specific_arg(true) is 6 bytes but SpecificInstruction::new().with_specific_arg(false).with_other_arg(6) is 12 bytes, that's more annoying
<re_irc>
< (@almindor:matrix.org)> e.g. Madctl is always one u8, something like VSCRDEF is "logically" 3 u16s (each representing a scrolling cutoff in pixels) but it needs to be sent over as 6 u8s in BE order for each of the u16s here
<re_irc>
< (@adamgreig:matrix.org)> if each instruction is a different type/enum variant then its builder methods can return differently-sized arrays np
<re_irc>
< (@adamgreig:matrix.org)> otherwise I'd probably have them store the data internally and have a method that returns a correctly-sized slice, or maybe it will be convenient to just give them a &mut[u8] at the end and they write into it?
<re_irc>
< (@almindor:matrix.org)> but how do I generalize them then?
<re_irc>
< (@almindor:matrix.org)> I mean in the end I need to do "anycommand.bytes() -> &[u8]" kind of thing (or "Iterator<Item = u8>")
<re_irc>
< (@almindor:matrix.org)> on the "physical interface" side I don't work with specific commands, just "any" command. Hence the heap issue of where to store the transformer logic "buffers"
<re_irc>
< (@almindor:matrix.org)> I guess I could do something like argument of "&mut [u8]" and assert out of too small ones or such
<re_irc>
<the tab openoor (spookyvision@{github,cohost})> so you want to go back and forth between raw chunk of bytes and a parsed representation (command) of that?
dc740 has quit [Remote host closed the connection]
conplan has quit [Remote host closed the connection]
conplan has joined #rust-embedded
<re_irc>
<rjmp> Does anyone know any good ways to handle dependency mismatches like this between main app and a dependency crate?
<re_irc>
"struct 'stm32f0xx_hal::pac::TSC' and struct 'stm32f0::stm32f0x1::TSC' have similar names, but are actually distinct types"
<re_irc>
Indeed, stm32f0xx_hal includes "v0.14.0", and the other crate (to which I am trying to pass a TSC peripheral) includes "v0.15.1", but I don't think I've ever seen anyway to force this to match, even if one of them depends with "version = "*"".
<re_irc>
<rjmp> The driver crate can work, by simply accessing the peripheral registers. But I can't see any way to take ownership of a RegisterBlock, since the lower level crate has no way to know about or accomodate different PAC versions in the top level crate.
<conplan>
I've been trying to blink a LED on an ESP32, and whenever I try to compile. I get a _stack_end_cpu0
<conplan>
and the program simply halts. any idea as to what might be wrong
<conplan>
does anyone know why what stack_end_cpu0 means in terms if the ESP32
<conplan>
I've been truing to get this to compile for some time now
<Darius>
not sure why changing the GPIO would fix it tho
<Darius>
stack_end_cpu0 sounds like "oops ran into a stack canary"
IlPalazzo-ojiisa has joined #rust-embedded
causal has joined #rust-embedded
<re_irc>
< (@sirhcel:matrix.org)> I'm wondering how to implement a (i2c) device driver which supports both, e-h 1.0.0 and e-h 0.2.7. I've seen such implementations for peripherals (like an i2c master). Could anyone point me to a good example?
conplan has quit [Remote host closed the connection]
<re_irc>
<Ralph> is there a rust equivalent to the Arduino servo library (https://github.com/arduino-libraries/Servo)? i couldn't find one at first glance (it doesn't help that there's the Servo project from Mozilla - searching "servo rust" yields that as the primary results 😅).
<re_irc>
<the tab openoor (spookyvision@{github,cohost})> @irc_libera_conplan:psion.agg.io: like, your firmware crashes? You might just be out of memory. Are you doing a release build?
<re_irc>
<the tab openoor (spookyvision@{github,cohost})> ah, nevermind, check Darius' link I suppose
<re_irc>
<Ralph> thanks ! i actually have a working prototype program to control my servo, so i know how to get it to work in general (sorry for not having been clear about that before). i'm not using a separate servo controller, just using it directly with an on-board PWM which makes it relatively easy. i was more wondering if there isn't a generic crate which would deal with that so that not everyone has to re-invent the wheel (there...
<re_irc>
... are some convenience features in the Arduino space, the servo crate is one of them 🙂)
emerent has quit [Ping timeout: 260 seconds]
emerent has joined #rust-embedded
<re_irc>
< (@firefrommoonlight:matrix.org)> IMO hobby PWM servo setup is standard timer setup
<re_irc>
< (@firefrommoonlight:matrix.org)> For your hardware, eg MCU
<re_irc>
< (@firefrommoonlight:matrix.org)> The details will depend on use case and hardware specifics, not to be abstracted in a general servo lib
<re_irc>
< (@firefrommoonlight:matrix.org)> I'm using stm32 timers for elevon servos, for context
<re_irc>
< (@firefrommoonlight:matrix.org)> Also would much prefer a digital protocol, but that's regrettably not how most of these work
<re_irc>
< (@firefrommoonlight:matrix.org)> I think some are CAN though, which is nice
<re_irc>
< (@firefrommoonlight:matrix.org)> I'd prefer a digital protocol, but that's not how most of these work
<re_irc>
<Tech Guy> : there is a lot of c++ code, and I am having trouble with using safer-ffi
conplan has joined #rust-embedded
<conplan>
So i've been working on getting rust running on ESP32, and every time I try to blink a LED, the program faults and I get an error "??:??"
<conplan>
and then it just says esp32.cpu0
<conplan>
also, is it neccesary that I include the ld/ directory present in the hal
<re_irc>
< (@adamgreig:matrix.org)> 👋 hi room , meeting time again! just gluing an agenda together, we'll start in a few min
<re_irc>
< (@adamgreig:matrix.org)> ok, let's start! couple of release announcements, cortex-m-rt 0.7.2 is out with the new "global_asm!()"-based startup routine, replacing the old precompiled asm blobs, which also means we can now have features for things like setting vtor and sp at startup
<re_irc>
< (@adamgreig:matrix.org)> and riscv 0.10 is released with the single-hart critical-section impl
<re_irc>
< (@adamgreig:matrix.org)> , do you wanna summarise the new crates you've mentioned?
<re_irc>
< (@lulf_:matrix.org)> bunch of async drivers really, using the new embedded-hal-async and embedded-nal-async as well as newly released embassy stuff
<re_irc>
< (@adamgreig:matrix.org)> cool! so far so good with e-h-a then?
<re_irc>
< (@korken89:matrix.org)> It's nice, except stuck on 2022-10-28 nightly due to compiler bugs
<re_irc>
< (@korken89:matrix.org)> (fixing PRs are up though, so it should soon work on latest nightly again :D )
<re_irc>
< (@adamgreig:matrix.org)> the price we pay for those tasty unstable features :P
<re_irc>
< (@korken89:matrix.org)> Yeah, but it's soooo much nicer to use than GATs, so worth it :D
<re_irc>
< (@therealprof:matrix.org)> : That's an oddly specific version.
<re_irc>
< (@adamgreig:matrix.org)> I guess just the last release before the bug was introduced?
<re_irc>
< (@korken89:matrix.org)> Yeah
<re_irc>
< (@korken89:matrix.org)> The PRs to fix it are up but not merged yet
<re_irc>
< (@korken89:matrix.org)> (they are linked in the PR)
<re_irc>
< (@korken89:matrix.org)> * PR in e-h-a)
<re_irc>
< (@adamgreig:matrix.org)> , wanna talk about the latest async interrupt stuff?
<re_irc>
< (@korken89:matrix.org)> Absolutely!
<re_irc>
< (@korken89:matrix.org)> After last weeks meeting and I discussed how to do this based on a few ideas, and he came to the conclusion that going for a "ecosystem trait" was maybe not needed as you could probably make it work just as well with a little bit of HAL code, sidestepping the "cortex-m-interrupt" crate completely
<re_irc>
< (@korken89:matrix.org)> I was not sure how to do it back then, but now I have made code examples for it
<re_irc>
< (@korken89:matrix.org)> Where I partially ported the "nrf-hal" to async
<re_irc>
< (@korken89:matrix.org)> Nothing fancy and a bit rushed
<re_irc>
< (@korken89:matrix.org)> But it shows that one can do all this in HALs
<re_irc>
< (@korken89:matrix.org)> No need for an external crate
<re_irc>
< (@adamgreig:matrix.org)> so in the end it becomes a nice design pattern for HALs to copy when they want to let users register interrupt handlers with the HAL
<re_irc>
< (@adamgreig:matrix.org)> cool
<re_irc>
< (@korken89:matrix.org)> Indeed
<re_irc>
< (@korken89:matrix.org)> The only thing that worries me is dissemination of this knowledge
<re_irc>
< (@korken89:matrix.org)> With a crate it would hopefully be a "standard" in the ecosystem, with this I guess .. blog post?
<re_irc>
< (@korken89:matrix.org)> But I can't really motivate the added complexity of an external crate when it is this easy to do in the HAL in the end
<re_irc>
< (@9names:matrix.org)> There aren't _that_ many HALs to notify that this exists
<re_irc>
< (@therealprof:matrix.org)> A crate doesn't necessarily make things easier to use.
<re_irc>
< (@korken89:matrix.org)> Exactly, only easier to point to
<re_irc>
< (@adamgreig:matrix.org)> I think HALs already do copy good ideas from each other anyway
<re_irc>
< (@korken89:matrix.org)> I think so too, there just has to be "the first" to do this
<re_irc>
< (@adamgreig:matrix.org)> maybe it would be nice to write up a single blog post as a thing to point at, we could also stick it on the embedded-rust blog
<re_irc>
< (@korken89:matrix.org)> Which gives you nice errors
<re_irc>
< (@korken89:matrix.org)> Like "SpiToken does not impl InterruptToken<GPIOTE>"
<re_irc>
< (@korken89:matrix.org)> If you mix them
<re_irc>
< (@adamgreig:matrix.org)> does the HAL then have to write a macro for every interrupt the user might register?
<re_irc>
< (@korken89:matrix.org)> Yes
<re_irc>
< (@adamgreig:matrix.org)> but I guess it can do arbitrarily clever macros if that's useful, to do lots of interrupts in one go or something
<re_irc>
< (@korken89:matrix.org)> Or macros that expand to multiple registrations
<re_irc>
< (@korken89:matrix.org)> Indeed
<re_irc>
< (@korken89:matrix.org)> And it's macros-by-example
<re_irc>
< (@adamgreig:matrix.org)> and that could still be a single token I suppose
<re_irc>
< (@korken89:matrix.org)> So no need for fancy proc-macros
<re_irc>
< (@adamgreig:matrix.org)> yea, that keeps it easy at least
<re_irc>
< (@korken89:matrix.org)> Absolutely
<re_irc>
< (@9names:matrix.org)> I wonder if this will work better for riscv interrupts too...
<re_irc>
< (@korken89:matrix.org)> If a driver uses multiple IRQs it canstill be a single token
<re_irc>
< (@korken89:matrix.org)> * can still
<re_irc>
< (@korken89:matrix.org)> And if you try to double register an interrupt you get the old name clash of the IRQ name
<re_irc>
< (@korken89:matrix.org)> : I think this should be just as fine for RISC-V
<re_irc>
< (@grantm11235:matrix.org)> Does it have to be "register_spim0_interrupt!(Spim0Token);" instead of "let spim0_token = register_spim0_interrupt!();"?
<re_irc>
< (@korken89:matrix.org)> There is nothing Cortex-M specific here
<re_irc>
< (@korken89:matrix.org)> : Not really, it's up to the HAL author then
<re_irc>
< (@korken89:matrix.org)> But as the token can't be misused there is no need to use ownership rules to move the token around
<re_irc>
< (@korken89:matrix.org)> But yeah, this is take 3 on this issue and I think this is about as simple as it gets :)
<re_irc>
< (@adamgreig:matrix.org)> something like "let token = register!();" does seem a more natural syntax, I was looking to see where the token came from that was being "passed into" the macro at first
<re_irc>
< (@adamgreig:matrix.org)> but yea, no reason the hal macro can't work that way right
<re_irc>
< (@grantm11235:matrix.org)> It could be simplified to "hal::Foo::new(register_foo_interrupt!());"
<re_irc>
< (@adamgreig:matrix.org)> well I guess it has to be outside of function scope so maybe it can't literaly be "let"?
<re_irc>
< (@korken89:matrix.org)> Yeah, no problem at all if the HAL wants to do it that way :)
<re_irc>
< (@adamgreig:matrix.org)> or can it be called inside a function to return something?
<re_irc>
< (@korken89:matrix.org)> This is how take 1 did it
<re_irc>
< (@adamgreig:matrix.org)> I assume it's expanding into a new function declaration that is the interrupt handler so idk if such a thing can go inside another function's argument list...
<re_irc>
< (@korken89:matrix.org)> You can return copies of the token via a function if that is desired
<re_irc>
< (@korken89:matrix.org)> Should be fine
<re_irc>
< (@korken89:matrix.org)> As it's just a statement
<re_irc>
< (@adamgreig:matrix.org)> fun
<re_irc>
< (@korken89:matrix.org)> I tried this with take 1 and it worked out fine
<re_irc>
< (@adamgreig:matrix.org)> what's the advantage to having the token at all vs just calling the macro when creating the hal driver, then?
<re_irc>
< (@korken89:matrix.org)> You can have multiple drivers wanting the same IRQ
<re_irc>
< (@korken89:matrix.org)> Without the token you can't make sure which driver has the right to take the token
<re_irc>
< (@korken89:matrix.org)> So you can generate an IRQ for driver 1 but pass it to driver 2
<re_irc>
< (@adamgreig:matrix.org)> I was imagining more like "driver::new(register_interrupt!())" which would have the same checks that the token is right, but you wouldn't have any way to have two drivers use the same irq
<re_irc>
< (@korken89:matrix.org)> If there is only a 1:1 relationship with IRQ:Driver I'm not sure the token is needed
<re_irc>
< (@adamgreig:matrix.org)> got it
<re_irc>
< (@adamgreig:matrix.org)> so I guess maybe some HALs don't have a token and others do, or maybe some drivers do or some don't, depending on what's necessary or convenient
<re_irc>
< (@korken89:matrix.org)> Yeah
<re_irc>
< (@korken89:matrix.org)> It's a good + of this approach, the idea is quite flexible
<re_irc>
< (@adamgreig:matrix.org)> I guess the HAL can't just call the macro itself because then the interrupt would always be registered in the HAL even if the user doesn't ever create that driver?
<re_irc>
< (@korken89:matrix.org)> Correct, then you get eager interrupt allocation
<re_irc>
< (@korken89:matrix.org)> Even if the driver is unused
<re_irc>
< (@korken89:matrix.org)> Oh yeah
<re_irc>
< (@korken89:matrix.org)> Another reason for the token
<re_irc>
< (@korken89:matrix.org)> You can forget to do the registration
<re_irc>
< (@korken89:matrix.org)> As there is no token to give the driver
<re_irc>
< (@korken89:matrix.org)> You can't forget to do the registration
<re_irc>
< (@adamgreig:matrix.org)> there's still a "token", just the user never sees it?
<re_irc>
< (@grantm11235:matrix.org)> If the hal registers the interrupt in "Foo::new", it only actually registers the interrupt if the user calls "Foo::new", right?
<re_irc>
< (@adamgreig:matrix.org)> if you have "driver::new(register_interrupt!())", the macro returns a token that's immediately passed to the driver
<re_irc>
< (@korken89:matrix.org)> : That's fine
<re_irc>
< (@korken89:matrix.org)> : No, the name is allocated in the linker
<re_irc>
< (@adamgreig:matrix.org)> : no, if the hal itself contains the macro in new, it will always expand into that static function that claims the interrupt handler
<re_irc>
< (@henrik1965:matrix.org)> I’m new to embed and would like to know how to run/debug a cortex-m the “right” way. Have seen ‘cargo embed’ but not tried. I got a shell script running gdbserver to my jlink two years ago.
<re_irc>
< (@korken89:matrix.org)> As it's a "#[no_mangle]" C-like function
<re_irc>
< (@adamgreig:matrix.org)> hi ! we're in the middle of the weekly meeting atm so it's not the best time to ask for help, but cargo-embed is a good option for debugging! the other popular one is probe-run, but either should work well and they use the same technologies under the hood
<re_irc>
< (@korken89:matrix.org)> #[no_mangle]
<re_irc>
unsafe extern "C" fn IRQNAME() { ... }
<re_irc>
< (@adamgreig:matrix.org)> seems like a great idea ! I guess keep trying it out in nrf-hal and then a blog post for other hal authors to reference?
<re_irc>
< (@adamgreig:matrix.org)> how does it compare to what embassy does atm?
<re_irc>
< (@korken89:matrix.org)> This is the current plan!
<re_irc>
< (@korken89:matrix.org)> embassy follows the "take 1" approach today, but after the discussion with I think it would probably move to this approach instead
<re_irc>
< (@korken89:matrix.org)> This is a lot simpler :)
<re_irc>
< (@korken89:matrix.org)> Now that I have written a few drivers using this approach it's quite evident in how easy it is to use
<re_irc>
< (@korken89:matrix.org)> I hope my hacky async-nrf-hal can be a bit of a first-stab-reference for this
<re_irc>
< (@korken89:matrix.org)> That's all I have for today, if there is discussions feel free to ping me or write issues on the HAL repo :)
<re_irc>
< (@adamgreig:matrix.org)> cool, thanks for talking through it!
<re_irc>
<henrik_alser> Great job
<re_irc>
< (@korken89:matrix.org)> Thank you all for taking the time to come with feedback!
<re_irc>
< (@adamgreig:matrix.org)> does anyone have anything else they want to discuss today?
<re_irc>
< (@9names:matrix.org)> Do we want to run another Final Friday thing? I feel like the shoutout of new projects on twitter is a good vibe
<re_irc>
<henrik_alser> Separate modules or separate crates or feature gating?
<re_irc>
< (@lulf_:matrix.org)> henrik_alser: I generally try to support both blocking and async in crates, but 1) it's requires some more work in the driver internals, and 2) some unmaintained blocking crates might not be easy to add async support for.
<re_irc>
< (@frozendroid:matrix.org)> henrik_alser: that'd be a good idea. Ideally in a way where you can use feature gates in a very nice way to abstract between async/blocking
<re_irc>
< (@korken89:matrix.org)> henrik_alser: In my experiment HAL I implemented both, it's not that much different to write a blocking or async HAL
<re_irc>
<henrik_alser> Yeah that’s the approach i’ve taken too in embassy hal drivers i’ve PR:ed lately
<re_irc>
< (@korken89:matrix.org)> It's also quite nice to have both. E.g. in RTIC you want blocking drivers in "init" and the n async driver fot the app
<re_irc>
< (@korken89:matrix.org)> * then async driver for
<re_irc>
< (@korken89:matrix.org)> * when the app runs
<re_irc>
< (@lulf_:matrix.org)> the challenge mixing is when you need to rely on a blocking and/or async trait for your implementation, say e-ha serial vs e-h-a serial
<re_irc>
< (@lulf_:matrix.org)> * e-h
<re_irc>
<henrik_alser> Yes, mostly came up as i was porting the ssd1306 incl display-interface stuff to async the other day/week?
<re_irc>
< (@korken89:matrix.org)> Hmm, do you have an example? Sounds like it should be solved by scoped import of the trait
<re_irc>
< (@lulf_:matrix.org)> +I face when
<re_irc>
< (@korken89:matrix.org)> * traits
<re_irc>
< (@frozendroid:matrix.org)> : yep. and usually for accessory peripheral crates, you can reason about sync vs async quite the same, usually
<re_irc>
< (@therealprof:matrix.org)> henrik_alser: I hope I haven't missed a PR.
<re_irc>
< (@lulf_:matrix.org)> struct MyDriver<T> where T: embedded_hal::serial::Write. vs. T: embedded_hal_async::serial::Write
<re_irc>
<henrik_alser> I made a separate crate just for my use case but we were discussing it how they can live together
<re_irc>
< (@lulf_:matrix.org)> I'm not sure what the best approach is there, because they are very different traits
<re_irc>
< (@frozendroid:matrix.org)> : you still have the difference of an ".await" vs a "block!", but maybe using combinators makes more sense. either way with a macro this could probably easily be abstracted with feature gates
<re_irc>
<henrik_alser> : Not yet! :D
<re_irc>
< (@lulf_:matrix.org)> * traits, different usage
<re_irc>
< (@korken89:matrix.org)> Right, I see.
<re_irc>
< (@frozendroid:matrix.org)> an "await!" would be unfortunate, but if it can get easy abstraction of async / blocking, that might be a tradeoff worth it for peripheral crates
<re_irc>
< (@adamgreig:matrix.org)> (I have to run, thanks everyone! feel free to keep chatting about this though)
<re_irc>
<henrik_alser> Yeah i mean it’s not a problem per se, just wanted to bring up if we should try to have a unified approach
<re_irc>
<henrik_alser> Thanks
<re_irc>
< (@frozendroid:matrix.org)> Oh I think a unified approach would be great indeed. Getting interrupts in e-h-a would help to bridge the gap between blocking and async as well, I think
<re_irc>
< (@firefrommoonlight:matrix.org)> Does anyone have an example of how to implement and/or use the interrupt abstraction discussed above? How does it interact with RTIC and the Cortex-M crates? Thank you