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
IlPalazzo-ojiisa has quit [Quit: Leaving.]
emerent has quit [Ping timeout: 240 seconds]
emerent has joined #rust-embedded
crabbedhaloablut has quit [Quit: No Ping reply in 180 seconds.]
crabbedhaloablut has joined #rust-embedded
starblue has quit [Ping timeout: 252 seconds]
starblue has joined #rust-embedded
crabbedhaloablut has quit []
euphemism[m] has joined #rust-embedded
<GrantM11235[m]> You could use normal wifi and set up one of the devices as an access point (even if it isn't connected to the internet)
firefrommoonligh has quit [Quit: Idle timeout reached: 172800s]
<waveguide[m]> <euphemism[m]> "More dumb questions:..." <- > <@euphemism:matrix.org> More dumb questions:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/ixgsDjYkHakvAWpugWwroJgs>)
<waveguide[m]> > <@euphemism:matrix.org> More dumb questions:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/orVOVvbFrVnzJxFFKcMQQrqc>)
<waveguide[m]> > <@euphemism:matrix.org> More dumb questions:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/NyqdtlDJXhjiRBSjlZfIPvLS>)
<euphemism[m]> <waveguide[m]> "> <@euphemism:matrix.org> More..." <- Some clarifications: I'm hoping to use an RP2040 as my host, as I will be attempting to take advantage of https://github.com/Wren6991/PicoDVI to simplify my BOM. I don't know if the full 1.5 MB/s would be saturated or not. There's a 16bit, 44.1kHz stereo audio stream which I guess would be something like `0.1764` MB/s, and then a currently unknown amount of serial data which
<euphemism[m]> contains information for drawing a screen.
<euphemism[m]> > <@waveguide:matrix.org> Maybe an nrf7002 over QSPI to an m7 core? Bridging 12Mbps will be time consuming without significant care
<euphemism[m]> * Some clarifications: I'm hoping to use an RP2040 as my host, as I will be attempting to take advantage of https://github.com/Wren6991/PicoDVI to simplify my BOM. I don't know if the full `1.5 MB/s` would be saturated or not. There's a `16bit`, `44.1kHz` stereo audio stream which I guess would be something like `0.1764 MB/s`, and then a currently unknown amount of serial data which contains information for drawing a screen.
<euphemism[m]> Could you clarify what you mean by
<euphemism[m]> > Bridging 12Mbps will be time consuming without significant care
<euphemism[m]> * Some clarifications: I'm hoping to use an RP2040 as my host, as I will be attempting to take advantage of https://github.com/Wren6991/PicoDVI to simplify my BOM. I don't know if the full 1.5 MB/s would be saturated or not. There's a 16bit, 44.1kHz stereo audio stream which I guess would be something like 0.1764 MB/s, and then a currently unknown amount of serial data which contains information for drawing a screen (at
<euphemism[m]> 60 FPS).
<M9names[m]> sounds ambitious, to say the least. what sort of serial data are you thinking of for your video data?
notgull has quit [Ping timeout: 240 seconds]
notgull has joined #rust-embedded
<euphemism[m]> <M9names[m]> "sounds ambitious, to say the..." <- Not My Data™. It's a series of commands to draw characters and rectangles at a number of positions. Will try to do some testing with the device to see what the actual bounds are on the serial bitrate.
<euphemism[m]> Might just accept that an ever-shrinking part of this project will involve Rust. Found a new devkit for the NRF7002 @ $36.00 so I'll just pick that up and see where I end up.
<euphemism[m]> Oh. Someone just bought it. Okay.
<GrantM11235[m]> Are you building a wireless KVM or something?
<euphemism[m]> 🤔 Kinda, I guess. The dream is a little, battery-powered hat on the device, and a streaming-stick-esque dongle poking out of a TV.
<euphemism[m]> But with a focus on low latency as that is important for peak enjoyment.
<korken89[m]> <dirbaio[m]> "try passing linker args from..." <- Neat trick, I'll give it a try!
<korken89[m]> korken89[m]: Do you know how to make a `"-C", "linker=flip-link",` work in this kind of setup as well?
<korken89[m]> korken89[m]: `println!("cargo:rustc-linker-bins=flip-link");` follows the pattern, but not sure 😅
zupink0re has joined #rust-embedded
baiko0x has joined #rust-embedded
zupink0re has quit [Ping timeout: 252 seconds]
baiko0x has quit [Ping timeout: 246 seconds]
zupink0re has joined #rust-embedded
<MathiasKoch[m]> <JamesMunns[m]> "(that's why its marked ..." <- Hmm, couldn't quite shake this, so i'd just bring some more possibly relevant info to the table.
<MathiasKoch[m]> It seems to work for serde_cbor, which i would expect to have the same underlying identifier issue from a binary format, of only storing the variant identifier?
<JamesMunns[m]> cbor is self describing, iirc
<JamesMunns[m]> Postcard doesn't send field name/identifiers, while cbor is closer to "binary json"
<MathiasKoch[m]> ahh.. Fair enough point
<JamesMunns[m]> The issue is self describing vs non self describing formats, not binary vs text/human readable
<MathiasKoch[m]> gotcha 👍️
<JamesMunns[m]> Part of the reason postcard is so efficient (and fragile in some ways) is it just spits out "value value value value" on the wire, assuming both sides agree 100% on the ordering and meaning, while self describing formats spit out "key:value key:value key:value"
<JamesMunns[m]> Which is wasteful if you do 100% agree, but is very useful if you potentially or definitely dont
<JamesMunns[m]> Or in some cases even "key:type:value...", which json and I think cbor do
<JamesMunns[m]> `{ "key": 1234 }` has a lot of implicit type information! We know it's a dict, with a string key and a numerical value!
<JamesMunns[m]> Whereas postcard would just send essentially just send `0x03 b"key" 0xd2 0x04" on the wire
<JamesMunns[m]> s/"/`/
<JamesMunns[m]> So only 6 bytes, very efficient!, but if you don't know how to decode it you're in trouble
lulf[m] has joined #rust-embedded
<lulf[m]> A general rule I tend to use is: If you need to change the schema at different points in time for endpoint 'A' and 'B', or you need to store the data, use self-describing formats and/or at least version + a registry to lookup schema
<JamesMunns[m]> Or if it was a struct, e.g. struct { key: 0x04d2 } it would only send two bytes, just the integer value!
<JamesMunns[m]> Tbh I've considered making a more flexible, self describing version of postcard, and I don't think it would be very far from cbor, honestly.
<JamesMunns[m]> Hashmaps in postcard are encoded as basically an array of tuples, but structs are just a tuple of values
<JamesMunns[m]> * array of tlkey/val tuples, but
<JamesMunns[m]> * array of key/val tuples, but
<JamesMunns[m]> * Hashmaps in postcard are encoded as basically a slice of key/val tuples, but structs are just a tuple of values
<MathiasKoch[m]> Yeah, i completely get that.... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/dunjZERLjVAgprKCCFEUzJeV>)
<JamesMunns[m]> Yes, that's how postcard works
<JamesMunns[m]> But that's not what serde flatten does
zupink0re has quit [Ping timeout: 246 seconds]
<MathiasKoch[m]> I am not flattening anything here, i just want to deserialize to adjacent tag (given by identifier) and content (xxxInner)
<MathiasKoch[m]> Essentially converting my enum to a struct of two keys (tag, content) before serializing and vice-versa
<JamesMunns[m]> Yeah, I'm saying the serde attrs affect the proc macro generated codegen in ways that are confusing for postcard
<MathiasKoch[m]> Ahh, so my problem is most likely in the derived serialize here?
<JamesMunns[m]> Lemme hop on my computer, just waking up
<JamesMunns[m]> MathiasKoch[m]: Derived deserialize, actually iirc
crabbedhaloablut has joined #rust-embedded
<JamesMunns[m]> Okay, looking at your repro case
<JamesMunns[m]> lemme manually decode that, there's definitely a change in contents, probably the field names
<MathiasKoch[m]> Do notice you are looking at json :)
<JamesMunns[m]> oh, nope, thank you :)
<JamesMunns[m]> did I mention I just woke up? lol
<JamesMunns[m]> okay, so fixing that it DOES pass, which means the serialize side is fine
<MathiasKoch[m]> Hah xD No worries, just grateful for the extra set of eyes, no matter the shape of them :)
<MathiasKoch[m]> Cool
<MathiasKoch[m]> Might just be that i'm missing a check somewhere in my deserialize, or a deserialize_xxx impl
<JamesMunns[m]> I think it might be the use of deserializer.deserialize_identifier(self) or similar APIs
<JamesMunns[m]> postcard expects not to have identifiers on the wire at all (enum discriminants are different than identifiers)
<JamesMunns[m]> Using cargo-expand, we can see there's definitely a difference in the deserializers generated:
<JamesMunns[m]> (well, you hand-wrote the first one, the second one is the normal derive)
<JamesMunns[m]> And we can see, that the serialize behavior didn't change, which means there's no identifiers on the wire to decode, so that's actually a good thing!
<JamesMunns[m]> So `#[serde(tag = "mode", content = "config")]`
<JamesMunns[m]> transforms from `{ key: value }` to `{"mode": key, "config": value}`, as expected
<JamesMunns[m]> but rather than being a hashmap of kinds, it's doing it more like you would deserialize:... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/aqNPpAlTIXALAteOpADqiZXW>)
<JamesMunns[m]> this is feasible in json, because serde nominally transforms structs into `HashMap<String, Any>`.
<JamesMunns[m]> but postcard doesn't do that same transform
Darius has quit [Server closed connection]
Darius has joined #rust-embedded
<MathiasKoch[m]> Yeah, that fits with my observations from digging through.
<MathiasKoch[m]> Question then becomes, is there anything i can do in either serialize or deserialize to support this without breaking the json ser/de?
<MathiasKoch[m]> I don't mind hand-rolled impls for this, but the struct itself is going through some abstractions, which means the copy-paste version without tag & content, combined with `From/Into` is rather unfeasible for me :/
<JamesMunns[m]> I don't really have any ideas, unfortunately. You essentially need two ser/de impls: one for "json mode" and one for "postcard mode", since the `tag/content` transform is invalid for "postcard mode"
<JamesMunns[m]> And the only way to achieve that I'm aware of is by using separate types, either wrapper types SideTagged(MyType) vs Normal(MyType); or MyType1 vs. MyType2
<MathiasKoch[m]> Yeah.. Guess ill change my binary format, which is essentially for persisting state to flash, to something with a slightly bigger overhead, but without it being json. Something like cbor :/
<MathiasKoch[m]> Ohh.. Nevermind, i think i can do the into call in my storage layer (read/write)
Guest7221 has left #rust-embedded [Error from remote client]
Guest7221 has joined #rust-embedded
zupink0re has joined #rust-embedded
fu5ha[m] has joined #rust-embedded
<fu5ha[m]> <euphemism[m]> "Not My Data™. It's a series of..." <- Fwiw, *just* doing this in a way that can feed a 60hz output video on an rp2040 would be a hell of a challenge, not counting anything else..
starblue has quit [Ping timeout: 240 seconds]
starblue has joined #rust-embedded
zupink0re has quit [Quit: Leaving]
IlPalazzo-ojiisa has joined #rust-embedded
<euphemism[m]> <fu5ha[m]> "Fwiw, *just* doing this in a way..." <- Which part of this would be the bottleneck in your view?
<fu5ha[m]> Mostly the 'drawing graphics fast enough' part, if you have a highly compressed instruction set input over serial. It depends how much of the screen you want to change per frame. But even if you're only drawing a total of 1/8th of the screen per frame, that's still 160x120 pixels to draw.... you have a max 16ms time to do it, if you double buffer. At 252Mhz internal clock which you need for picodvi I believe, that's only (252000000
<fu5ha[m]> / 60) / (160 * 120) = ~200 clock cycles per pixel! In those 200 clock cycles per pixel you need to not only read serial data, but also compute what to draw and then actually write it into the next framebuffer so the other core can grab it and bang it out over dvi. Do keep in mind though that when you overclock the rp2040, you get degraded max peripheral clocks (i believe down to 12Mhz) so that would limit you even more as well. And
<fu5ha[m]> that's not even taking into account the other stuff you want it to be doing, like passthrough input!
thejpster[m] has quit [Quit: Idle timeout reached: 172800s]
therealprof[m] has quit [Quit: Idle timeout reached: 172800s]
Noah[m] has quit [Quit: Idle timeout reached: 172800s]
vollbrecht[m] has quit [Quit: Idle timeout reached: 172800s]
ni has quit [Server closed connection]
ni has joined #rust-embedded
<ryan-summers[m]> Is it possible to have cortex-m-rt use two different RAM sections for data vs stack? The H7 has, like, 5 discontinuous sections, and I'm going to need a pretty large stack. I figured it would make the most sense to link .data and stack into separate sections, since that helps with memory safety anyways
sourcebox[m] has quit [Quit: Idle timeout reached: 172800s]
<ryan-summers[m]> It looks like the answer is probably no without a custom linker script since cortex-m-rt defines the stack symbol etc. using the RAM memory section
mabez[m] has joined #rust-embedded
<mabez[m]> ryan-summers[m]: I think you'd need to copy and modify link.x from cortex-m-rt crate, the default one puts all those section in the same `RAM` memory segment
<ryan-summers[m]> Can you just keep a local copy in your repo and it'll pick that up?
<mabez[m]> s/section/sections/
<mabez[m]> ryan-summers[m]: Yeah, call it something different and move it to the out dir, then in `.cargo/config.toml` you can tell the linker to use your linker script instead of `link.x`
<ryan-summers[m]> Huh, https://docs.rs/cortex-m-rt/latest/cortex_m_rt/#_stack_start seems to indicate this actually should be pretty easy
<ryan-summers[m]> Well maybe I should read the docs before asking
<mabez[m]> ryan-summers[m]: Ah yeah for the stack start, you can override that, if you don't mind the other sections all going into RAM
<ryan-summers[m]> Yeah that would be fine here, I just have a random unused 512KB I want to move the stack into
<ryan-summers[m]> Which feels like such a weird thing to say for an embedded guy
<waveguide[m]> Do any other hals have something like a clock tree solver of sorts built in?
<waveguide[m]> I have 3 peripherals I may want to clock well, so I have what amounts of a system of equitions that I need to do a best fit on it feels like
<euphemism[m]> <fu5ha[m]> "Mostly the 'drawing graphics..." <- Thank you for taking the time to investigate this. A couple of things:
<euphemism[m]> There is no input pass through; this is a one-way remote display. The resolution of the described frame being drawn is 320x240, and it’s not full frame video or anything. Mostly only small areas update at any given time, barring changes to other views. I didn’t know about the degraded peripheral performance. That’s interesting.
<dirbaio[m]> spinfast: which chip? some stm32 hals have sort of that, where you specify target freqs and it tries to calculate best dividers, pll factors, etc
<waveguide[m]> e.g. "audio_clock_solver(sai1_freq, sai2_freq, sai3_freq)" is a function I think I need to concoct here, and its kind of wild... as actually there's different PLLs each can mux on, followed by a whole slew of various dividers... all to in the end generate a serial audio bit clock of a particular frequency
<waveguide[m]> imxrt10xx in this case, with 3 SAI (serial audio) peripherals
<dirbaio[m]> with time i've come to the opinion that doing it on-firmware is a mistake though. it's complex, the compiler is bad at optimizing it out
<waveguide[m]> yeah I wish I could write a const fn for this
<waveguide[m]> like, here's the output frequencies I want in rust, generate the clock tree settings
<dirbaio[m]> and on firmware you can only approximate. to get the actual best clock config you essentially need a full-blown SMT solver :P
<waveguide[m]> though maybe this is beyond the capabilities of a const fn... we already have some build.rs stuff
<waveguide[m]> yeaaaaaah
<waveguide[m]> maybe I'll provide the mutators for this stuff, then set it up by hand in the board clock tree config for now... most of the imxrt evks seem to use the same codec and little speaker hooked up to the medium quality sound peripheral
<dirbaio[m]> so it's best to calculate the config beforehand and hardcode it in the firmware
<waveguide[m]> like this thing can do sai3 -> mqs -> micro speaker
<waveguide[m]> which is neat I guess, no codec required
<dirbaio[m]> perhaps with some tool. ST has stm32cubemx which is quite good for it, not sure if imxrt has something similar
<waveguide[m]> can probably blast out some 90's quality midi vibes
<waveguide[m]> yeah I recall cubemx's clock tree config, mcux has something similar
<waveguide[m]> the tools are kind of dreadful in other ways though
<dirbaio[m]> yeah 🥲
<waveguide[m]> they really want to dump out C code
<waveguide[m]> like, in the gui you work out the clock tree and the output is just a big blob of C for the vendor hal...
<dirbaio[m]> user specifies a config, the hal just validates and applies it.
<dirbaio[m]> i'm actually refactoring embassy-stm32 rcc lately to remove all on-firmware clock solving :P
<waveguide[m]> that really does prevent clock scaling if you want that though
<waveguide[m]> like if you wanted to drop power modes by doing a bunch of clock/power gating and down clocking
<dirbaio[m]> not necessarily, you could have multiple configs and switch between them
<waveguide[m]> I guess you could pre-defined the states...
<waveguide[m]> that's kind of what mcux does, there's a predefined run and low power state I believe
<waveguide[m]> but again those feel pretty limiting
<JamesMunns[m]> (this is what I've always done, use the GUI tools to pick a couple of values, get the PLL config values, dump the solved P/N/M/Q/whatever values into the firmware itself)
<waveguide[m]> for audio this is particularly annoying I'd say
<waveguide[m]> the audio sample clock may be useful to change at runtime
<JamesMunns[m]> but yeah, depends on how autonomous/automatic/magical you want to be. But I've always been lucky enough where one or two const configs were acceptable
<JamesMunns[m]> but then again I don't do a lot of audio :D
<waveguide[m]> as would the number of channels being TDMed into the audio serial stream
<waveguide[m]> e.g. someone plugs in a microphone
<waveguide[m]> or line out
<waveguide[m]> or line out and speaker
<dirbaio[m]> you can always do a "tiny" clock solver in user code for just that application
<waveguide[m]> right
<dirbaio[m]> the problem with doing clock solving in the HAL is there's pressure to make it handle EVERYTHING for ALL use cases, which is not feasible
<waveguide[m]> yeah so then the HAL only provides ways to mutate and access clock tree settings and rates
<dirbaio[m]> yep
<waveguide[m]> up to application to maybe have a table around for various configs, makes sense
<waveguide[m]> I like it
<waveguide[m]> always make it an app problem not a hal problem, seems like a good mantra to repeat
<waveguide[m]> ✌️
<dirbaio[m]> lol
<dirbaio[m]> imo it's good to solve as much stuff in the HAL, but only as long as it's actually solveable
<dirbaio[m]> * the HAL as possible, but
<waveguide[m]> even providing the clock manipulation, config, and providing the current frequency is an interesting thing for this part... do the ST H7/F7 parts also have insane clock trees?
<waveguide[m]> imxrt has like 6 plls
<dirbaio[m]> yep, ST has up to 3 plls and tons of muxes 🙃
<JamesMunns[m]> IMO the imxrt is definitely more complex, but the H7s get pretty close from memory
<dirbaio[m]> H5 adds more muxes, U5 is quite insane too
<waveguide[m]> yeah... imxrt is wildly configurable
<waveguide[m]> want mmio accessible hyperflash/hyperram with video, audio, enet, and usb all going?
<waveguide[m]> sure thing bos
<waveguide[m]> * sure thing boss
<waveguide[m]> almost feels like the only real seperation here between imxrt and imx is a ddr controller and mmu...
<JamesMunns[m]> The datasheet isn't 4k+ pages for no reason
<waveguide[m]> * and mmu... I mean I know its more than that... but my goodness
<JamesMunns[m]> there's... a lot of flexibility and options in there
<waveguide[m]> ya, the rt500/rt600 are I don't even know... those are also completely different
<waveguide[m]> m33 + xtensa hifi + a half dozen flexcomms
<waveguide[m]> the audio evk has like 8 trs plugs and I think fistful of dmics
<waveguide[m]> s/8/7/
<waveguide[m]> nrf54 has riscv cores doesn't it?
<JamesMunns[m]> (nordic, to Arm): don't worry! That new core means nothing to me! it's just for low power stuff, no threat!
<JamesMunns[m]> waveguide[m]: yep!
<waveguide[m]> It's gotta be tough to compete with espressif at this point
<waveguide[m]> yeah, they don't want to lose whatever pricing deal they have
<waveguide[m]> * they have, though maybe that's a new way to negotiate "give us a discount on arm designs or we're going all in on riscv"
<waveguide[m]> aren't the espressif modules all fcc certified too? like for $2.50 to get wifi/ble/etc, more sram and flash, and fcc certified... what is nordic going to give me for that
<waveguide[m]> * fcc certified, and a rust sdk... what
<waveguide[m]> https://www.espressif.com/en/support/documents/certificates sure looks like its fcc certified, that's $10k if you go the non-module route with a nrf part
<waveguide[m]> * that's $10k usd to certifiy if you
<waveguide[m]> * that's $10k usd to certify if you
AdamHott[m] has quit [Quit: Idle timeout reached: 172800s]
<dirbaio[m]> Nordic still wins in low-power
firefrommoonligh has joined #rust-embedded
<firefrommoonligh> Re HAL clock solvers: IMO letting the user specify dividers, with one or more sane defaults is the way to go
<waveguide[m]> <dirbaio[m]> "Nordic still wins in low-power" <- yeah I guess that would be an interesting break down to see someone do a comparison on
<waveguide[m]> with real world firmware, not some made up vendor number under ideal conditions
<waveguide[m]> * world firmware and boards, not
thejpster[m] has joined #rust-embedded
<thejpster[m]> <fu5ha[m]> "```..." <- > <@fu5ha:matrix.org> ```... (full message at <https://catircservices.org/_matrix/media/v3/download/catircservices.org/LalHoxCYfXUPiyGZUkACVgIU>)
lkostka[m] has quit [Quit: Idle timeout reached: 172800s]
<thejpster[m]> Try running the SPI bus slower? Or faster? And maybe grabbing a bus analyser to watch the traffic.
<thejpster[m]> Don’t forget init must be under 400 kHz. After that you can go to whatever speed the card tells you or your wiring can handle.
ilpalazzo-ojiis4 has quit [Quit: Idle timeout reached: 172800s]
Guest7221 has left #rust-embedded [Error from remote client]
neceve has joined #rust-embedded
<fu5ha[m]> Yeah I init at 400khz, then up the bus to 20Mhz. Hmm. Maybe I'll try init even lower. Then time to break out the scope or something maybe
<fu5ha[m]> The weird thing is it seems to succeed init and reading the mbr at 0 and bpb at 2048. But then fails at 2049 😕
Guest7221 has joined #rust-embedded
<thejpster[m]> That is odd. Can you dd it on Linux?
<thejpster[m]> Also do you have CRCs enabled? Does your card support CRCs? It’s in the CSD I think.
<thejpster[m]> 20 MHz is pretty fast. What’s the micro? If it’s a 2040 did you put the pins in high speed mode?
Guest7221 has left #rust-embedded [Error from remote client]
Guest7221 has joined #rust-embedded
barafael[m] has quit [Quit: Idle timeout reached: 172800s]
barafael[m] has joined #rust-embedded
<barafael[m]> TIL one can CTRL+Z the probe-rs process run via cargo run, stopping the firmware. fg brings it back normally. Is this hacky or what?
<M9names[m]> Sounds like perfectly normal Unix process control to me
<dirbaio[m]> it's not guaranteed to stop the firmware. it'll only stop if the RTT buffer gets full.
crabbedhaloablut has quit []
NaomiLiu[m] has quit [Quit: Idle timeout reached: 172800s]
d3zd3z[m] has quit [Quit: Idle timeout reached: 172800s]
notgull has quit [Ping timeout: 246 seconds]
notgull has joined #rust-embedded