emerent has quit [Killed (calcium.libera.chat (Nickname regained by services))]
emerent_ is now known as emerent
ymwm_ has quit [Remote host closed the connection]
fabic_ has joined #rust-embedded
starblue has quit [Ping timeout: 240 seconds]
starblue has joined #rust-embedded
gsalazar has joined #rust-embedded
cr1901_ has joined #rust-embedded
cr1901 has quit [Ping timeout: 260 seconds]
fabic_ has quit [Ping timeout: 246 seconds]
<re_irc>
<gauteh> Hi, is there any reason to leave out defmt log in devices that go out in the field. There's a small chance I will be debugging them.
<re_irc>
<korken89> gauteh: Leave out as in disable completely or not?
<re_irc>
<korken89> Just use the "DEFMT_LOG" level when building the binary
<re_irc>
<gauteh> As in unsetting DEFMT_LOG
<re_irc>
<korken89> Set "DEFMT_LOG=off"
<re_irc>
<gauteh> Yeah, but I mean, there's a small chance I need to attach and look at the output - so if the overhead is not too great I'd leave it on
<re_irc>
<korken89> Then leave it on :)
<re_irc>
<gauteh> :D great!
<re_irc>
<korken89> E.g. in our products we run "DEFMT_LOG=error"
<re_irc>
<korken89> To only have error logging in the field
<re_irc>
<gauteh> Ok!
<re_irc>
<korken89> We do however transport all defmt data to a server and decode logs from all units in the field
<re_irc>
<korken89> So we never "connect to the device"
<re_irc>
<gauteh> Ok
<re_irc>
<korken89> Depending on what works the best for you :(
<re_irc>
<korken89> * :)
<re_irc>
<gauteh> I do have a similar option for low-volume logging
<re_irc>
<gauteh> I log panics and some manually formatted errors, but haven't had time to set it up with defmt yet.
<re_irc>
<korken89> Nice
explore has quit [Quit: Connection closed for inactivity]
fabic_ has joined #rust-embedded
<re_irc>
<caspinol> As a side effect of different app i'm working on i accidentally made a LCD touch controller driver. I didn't touch driver crate anywhere so decided to release it https://github.com/VersBinarii/xpt2046
<re_irc>
<riskable> If my code is referencing a "const" in another file in my crate and I put a little alias at the top like, "const NUM_LEDS: usize = config::LEDS_NUM_LEDS;" will that end up adding to my program size or will the compiler optimize that sort of thing away?
<re_irc>
<K900> "const" values are not stored in a fixed location in the resulting binary
<re_irc>
<K900> They're effectively substituted at compile time
<re_irc>
<riskable> K900: Ahh, so then it shouldn't matter if I add little shortcuts like that at the top of my files then ๐
<re_irc>
<riskable> What if I changed the type though? "const NUM_LEDS: usize = config::LEDS_NUM_LEDS as u16;" Would that matter?
<re_irc>
<riskable> I assume not
<re_irc>
<riskable> What if I changed the type though? "const NUM_LEDS: u16 = config::LEDS_NUM_LEDS as u16;" Would that matter?
<re_irc>
<K900> Same thing
Foxyloxy has joined #rust-embedded
fabic_ has quit [Ping timeout: 248 seconds]
fabic_ has joined #rust-embedded
cr1901_ is now known as cr1901
<re_irc>
<riskable> I'm having trouble working with embedded_hal's "DynPin". I have:
<re_irc>
let millivolts: u16 = adc.read(&mut pin.into()).unwrap();
<re_irc>
...and this is the error I'm getting:
<re_irc>
let pin: &DynPin = analog_pins.get_pin::<Infallible>(mux).unwrap();
<re_irc>
<riskable> Why doesn't embedded_hal just require that various HALs include a function or table or similar that lets you return a "DynPin" to its original type (say, "Pin<Gpio26, FloatingInput>") without having to know the precise type in question? I mean, it already stores a "DynPinId" which could--in theory--be used later to look up what pin it used to be. That way you could make something like an array of "DynPin"s and pull the...
<re_irc>
... exact pin out of said array like so: "my_dynpins_array[26].get_pin()". Then "get_pin()" would simply look at the pin number it had when it was created and simply return something like "return match Self::PINS { 0 => Gpio0, 1 => Gpio1, ... }"
<re_irc>
<newam> You could use dynamic types with vtables, but that seems... wrong for GPIOs.
<re_irc>
<riskable> Why give each pin a specific type then? Why not just have a Gpio struct with an "impl" that takes the pin number as the first argument?
<re_irc>
<dirbaio> maybe HALs could impl TryInto to convert from degraded to concrete types
<re_irc>
<dirbaio> like, you can convert from DynPin to Gpio12, but that'd fail if the DynPin is not actually gpio 12
<re_irc>
<dirbaio> I don't think any HAL does
<re_irc>
<dirbaio> not sure what you'd use it for
<re_irc>
<dirbaio> riskable: in most chips, a given peripheral can only use a limited set of pins. For example SPI0 SCK can only be Gpio12 or Gpio16
<re_irc>
<newam> riskable: You can only implement traits e.g. alternate functions for concrete types.
<re_irc>
You could use const generics I suppose, but that doesn't solve the problem.
<re_irc>
<dirbaio> Having a different type per pin allows checking that at compile time
<re_irc>
<riskable> It's more like: I need to know what the precise pin type (e.g. "Gpio26") is ahead of time. I can't write a dynamic function that just takes a "DynPin" and passes it to "adc.read()".
<re_irc>
<newam> riskable: impl AdcPin for Gpio26 {}
<re_irc>
no?
<re_irc>
fn read<P: AdcPin>(pin: &mut P);
<re_irc>
<riskable> I can write a function that takes "DynPin" but "adc.read()" requires a pin-specific type and there's no way to convert it back without providing that specific type when calling "into()"
<re_irc>
<dirbaio> is this for the "make a firmware portable across boards" thing?
<re_irc>
<riskable> dirbaio: Yeah, haha
<re_irc>
<riskable> I'm _so close_!
<re_irc>
<dirbaio> make the board-specific code construct the entire adc/spi/i2c/etc peripherals, and/or export type aliases
<re_irc>
<riskable> There's functions like "set_high()" and "is_low()" etc etc for "DynPin" but you can't pass a "DynPin" to "adc.read()"
<re_irc>
<riskable> So it works fine for digital IO operations but not analog
<re_irc>
<dirbaio> if you make the all the code use that, you should never need to degrade to DynPin
<re_irc>
<riskable> ...where "mux" would represent a specific analog multiplexer (and the pin it's connected to)
<re_irc>
<riskable> ...but doing it this way requires that every board-specific "main.rs" have this _super_ repetitive code that does all the ADC operations/checks and whatnot. There seems to be _literally_ no way I can write a function that iterates over a list of ADC pins and reads them
<re_irc>
<riskable> +(generic)
<re_irc>
<riskable> I mean, it's not a deal-breaker but it's _super_ annoying
<re_irc>
<riskable> ...because if I was just implementing a keyboard matrix that strictly used digital IO I wouldn't have this problem
<re_irc>
<riskable> HAL MAKERS ARE DISCRIMINATING AGAINST ANALOG FOLKS! haha ๐
<re_irc>
<K900> Do we have anything QMK-ish for keyboard firmware in Rust yet?
<re_irc>
<K900> Specifically targeting stm32
<re_irc>
<ruabmbua> Hm I think some laptop vendor has written all their FW + keyboard FW in rust
<re_irc>
<ruabmbua> Or was I dreaming? ;-P
<re_irc>
<newam> system76 I think?
<re_irc>
<riskable> K900: Well there's some board-specific firmwares out there. Most use Keyberon: https://github.com/TeXitoi/keyberon (I'm using it too)
<re_irc>
<riskable> I'm trying to make a QMK-like firmware for analog keyboards (though I supposed you could use it for regular ones too) and it's turning out to be really, really freaking hard because there's no way to handle analog reads in a generic sort of way. 90% of the code ends up being board-specific.
<re_irc>
<dirbaio> riskable: the HALs should support DynAdcPin for that
<re_irc>
<riskable> dirbaio: No HALs have "DynAdcPin". I just checked haha
<re_irc>
<riskable> The way it works in "rp2040_hal" is the ADC-specific pins end up getting a special "impl Channel<Adc> for Pin<Gpio26, FloatingInput>" (one for each Gpio<num>)
<re_irc>
<riskable> ...and "adc.read()" only takes pins that have that "impl"
<re_irc>
HAL could have a "struct DynAdcPin<Adc>" and "impl<Adc> Channel<Adc> for DynAdcPin<Adc>"
<re_irc>
<dirbaio> so you can use either concrete or degraded types
<re_irc>
<riskable> That would be fantastic
Abhishek_ has quit [Quit: Connection closed for inactivity]
<re_irc>
<dirbaio> someone asked about this in the embassy channel today
<re_irc>
<dirbaio> and that's what we're going to do
<re_irc>
<dirbaio> the nice thing is it still prevents using non-adc-capable pins at compile time
<re_irc>
<firefrommoonlight> I wonder how generisiable ADC reads are. I can't comment since I'm only familiar with STM32, and offboard (eg I2C) ADCs
<re_irc>
<firefrommoonlight> For multiple channels on STM32 internal, my intuition is to use a sequence via DMA
<re_irc>
<firefrommoonlight> in continuous mode, or triggered using a basic timer, depending on details
<re_irc>
<firefrommoonlight> (I speculate it wouldn't translate directly to a diff platform)
<re_irc>
<firefrommoonlight> Maybe circular, maybe not, depending on the specifics
<re_irc>
<firefrommoonlight> Gets even more interesting if you're combining reads from multiple ADC periphs
<re_irc>
<firefrommoonlight> *I need to review this stuff; ADC is one of the more complicated periphs, (probably in a tie with timers...)
<re_irc>
<firefrommoonlight> There's also the injected vs direct choice
<re_irc>
<firefrommoonlight> *If you're just using a single channel, things get simpler
<re_irc>
<riskable> firefrommoonlight: Yeah in future boards I'm thinking about running all multiplexer channels through another multiplexer that connects to a single pin on the MCU. It will take up three more GPIO pins but it should simplify the logic quite a lot and also make it so you can have _absurd_ amounts of analog inputs if the ADC speed is fast enough ๐
<re_irc>
<riskable> I calculated that with an STM32F411CEU6 Black Pill you can realistically get 2560 analog inputs using the multiplexers-through-a-multiplexer setup and still come in just barely under 1ms to read them all ("((3+12)/42)*2560 == 914.29"ยตs)
<re_irc>
<riskable> Of course you still need clock cycles to actually figure out if a key is pressed and whatnot so _in reality_ you're probably better off using a few less than that ๐
<re_irc>
<riskable> OK I'm mostly done with moving all the board-specific stuff into its own "src/bin/<board>" directory. The resulting "main.rs" is ~650 lines. About half of that is boilerplate and the other half is hardware-specific stuff. I will be able to reduce it further once I figure out how to handle displays.
neceve has quit [Ping timeout: 240 seconds]
<re_irc>
<Lachlan Sneff> Just started getting compile errors for defmt. Something about an unsafe function?
<re_irc>
error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
<re_irc>
<newam> "defmt = "=0.3.0"" will fix that. Not sure about the root cause though.
<re_irc>
<Lachlan Sneff> That works, thank you
<re_irc>
<kelleyk> Is anyone aware of a good example of an "embedded_hal"-aware GPIO expander driver?
<re_irc>
<kelleyk> I'm using an MCP23017 in my design and I've found two different drivers, but neither provides an "OutputPin"-style interface which makes them hard to use with other crates.
<re_irc>
<kelleyk> Wondering if there's an option I'm missing before I go start writing something; and if I do, a good example of a driver for another chip would be great, since I'm still learning to be a Rustacean.