ChanServ changed the topic of #rust-embedded to: Welcome to the Rust Embedded IRC channel! Bridged to and logged at, code of conduct at
neceve has quit [Ping timeout: 246 seconds]
fabic has joined #rust-embedded
mrkajetanp has quit [*.net *.split]
sauce has quit [*.net *.split]
sauce has joined #rust-embedded
mrkajetanp has joined #rust-embedded
emerent has quit [Ping timeout: 240 seconds]
emerent_ has joined #rust-embedded
gsalazar has joined #rust-embedded
<re_irc> <ub|k> 9names: only seems to happen on macOS. I'll try later with a different cable. But it works on in Linux with it... weird.
<re_irc> <heksa> adamgreig: Oh. That's pretty similar to what we do with Kactus2 and IP-XACT for RISC-V SoCs. For the implemented peripherals we also 'just' need to map the register names into macros, which generate a HAL.
fabic has quit [Ping timeout: 276 seconds]
cr1901_ has joined #rust-embedded
cr1901 has quit [Ping timeout: 260 seconds]
neceve has joined #rust-embedded
fabic has joined #rust-embedded
starblue has quit [Ping timeout: 256 seconds]
starblue has joined #rust-embedded
<re_irc> <TimSmall> 762spr: I've found it interesting to look at the assembly which is produced by Rust HAL code. The majority of things come out pretty lean in my experience (even for surprisingly "high level" constructs which you might not expect to result in tight code).
fabic has quit [Ping timeout: 260 seconds]
fabic has joined #rust-embedded
<re_irc> <riskable> I'm working on this "universal" keyboard firmware of sorts that's supposed to work with "everything" (analog keyboards, digital keyboards, unlimited rotary encoders, unlimited displays, unlimited lighting outputs, etc) and I'm trying to make an ergonomic interface for making it work with any given board/hardware. What I've come up with is modules for keyboard stuff, dealing with multiplexers, encoders, infrared,...
<re_irc> ... displays, etc and they all do the "hard part" in that they figure out which keys are down/up, what direction an encoder is moving, what button was pressed, etc etc but in order to do that they need to get passed the state of everything (hardware wise). I've made all these modules with an "update_state()" function that takes a ("&mut") "PerhipheralState" argument and (currently) mutates it in place, returning true/false...
<re_irc> ... depending on whether or not something was changed. However, I'm wondering if it would be better to force all my "update_state()" functions to take _ownership_ of "PerhipheralState" and return it after it's done making changes. What do you guys think is the "better way"?
<re_irc> <K900> Return a delta
<re_irc> <K900> Or more specifically probably a list of events
<re_irc> <riskable> K900: Oooh, that's not a bad idea... But then I have to come up with a way to make Keyberon's events work for things that aren't really "keyboard" (like display stuff). Or I suppose I could just make up my own event enum
<re_irc> <K900> I've been starting my own keyboard firmware thingy and I ended up just dropping Keyberon
<re_irc> <K900> Because it doesn't really fit what I'm trying to do
<re_irc> <K900> (which is mostly to stop describing things in terms of layers)
<re_irc> <riskable> Right now my "Encoder::AnalogEncoder" (which is an enum) needs to mutate the "states" variable it gets passed so it can mark its respective analog channels as "rising" and reset their "default" values when an event gets triggered. So the "update_state()" functions will still need to mutate "states" in some cases.
<re_irc> <K900> I've been going for a kind of an FRP thing
<re_irc> <K900> With all the state being inside the tasks
<re_irc> <riskable> K900: Yeah some parts of it are getting in my way now that I'm "diving deeper" as it were... For example, its mechanism for creating the Keyboard object you pass over USBHid has a hard-coded 10ms polling interval. I need that to be configurable.
<re_irc> <riskable> K900: FRP?
<re_irc> <K900> Functional reactive programming
<re_irc> <K900> Basically just describing everything as streams of events
<re_irc> <K900> And functional operations on those streams
<re_irc> <riskable> K900: Ahh, I get it. I've worked with systems that do that before. Just never heard of it called FRP
<re_irc> <riskable> I am _very_ tempted to move over to a message-passing architecture with the observer pattern
<re_irc> <K900> So I've got a stream of key up/down events that goes into the actual mapping logic
<re_irc> <K900> And then that shoves events into a sink that updates in-memory state
<re_irc> <K900> That actually gets scanned out
<re_irc> <K900> I'm still not super convinced it's a good idea
<re_irc> <K900> But it's kinda working so far
<re_irc> <riskable> ...because I want to be able to efficiently take advantage of multiple cores without having things get super complicated for people building their "src/bin/<some board>/"
<re_irc> <riskable> How are you handling configuration and key mapping?
<re_irc> <K900> So far I'm just hardcoding it
<re_irc> <K900> And I think I'll stick to that
<re_irc> <K900> This is being very, uh, ~suckless~ intentionally minimalistic
<re_irc> <riskable> Right now I'm still using Keyberon's "" style but I know I'm going to have to make a "" mechanism that converts some sort of multiplexers/matrix-to-keys "Map.toml" or similar
<re_irc> <riskable> I'm doing the opposite of minimalistic, haha
<re_irc> <K900> I absolutely don't want to make it scale up
<re_irc> <K900> Unless it happens by accident
<re_irc> <K900> Right now I'm running QMK and it's way too big
<re_irc> <K900> Not like bytes but like brainspace
<re_irc> <riskable> I _needed_ to write my own firmware from scratch (no option) because my keyboard is analog and there's no open source analog firmwares to build off of. Once I started down that path it became a bit of a rabbit hole. Now that I've emerged from the rabbit hole I've got some mechanisms that can be used to build _any_ sort of keyboard--not just analog. I figure that if I'm going to make a firmware I might as well make it...
<re_irc> ... something that can--in theory--work on anything 👍
<re_irc> <K900> So I'm building a thing that will do exactly one thing
<re_irc> <riskable> OMG QMK is soooooo pointlessly complicated
<re_irc> <K900> And that one thing will be exactly what I want my keyboard to do
<re_irc> <riskable> When I started down this path I tried very, very hard to modify QMK to work with my analog keyboard design and I just couldn't get it working
<re_irc> <K900> I haven't even looked at QMK code much
<re_irc> <K900> Just the configuration and the tooling
<re_irc> <riskable> It's a giant mess!
<re_irc> <riskable> It has hard-coded assumptions _everywhere_
<re_irc> <K900> I am K900's complete lack of surprise
<re_irc> <riskable> ...and navigating the "ifdef" statements requires intense focus, haha
<re_irc> <riskable> Going back and forth between the code and the header files makes me wish I had like 4 monitors haha
<re_irc> <riskable> I think the "big innovation" my firmware will bring to the table is the ability to work with _any_ kind of analog keyboard. If you've got sensors (optical, hall, capacitive, etc) that are changing values based on keypresses my firmware can be configured to handle that and give you 1ms polling with fancy lighting and display support
<re_irc> <riskable> Also, I _may_ have some innovative stuff to give to the embedded Rust community in regards to compile time configuration and code generation
<re_irc> <K900> So basically you're doing the exact opposite of what I'm doing
<re_irc> <riskable> The way I've got it working now you can add as many "[[encoder]]" entries to the "Config.toml" as you want and a "" will get automatically generated with the necessary variables/struct definitions (as "const") in a nice, "<'static>" array of encoders (and it supports every kind of rotary encoder that exists, haha) 👍
<re_irc> <riskable> So in your code you can always just refer to "config::ENCODERS" and access that array
<re_irc> <riskable> Now that I've got that mechanism working/figured out I'm going to apply it to _everything_ haha
<re_irc> <riskable> Unlimited "[[display]]" entries. Unlimited "[[remote]]" (infrared remote controls). Unlimited everything! Muwahahaha!
<re_irc> <riskable> ...but it won't mean much if making my firmware work with any given board is a huge pain in the ass
<re_irc> <riskable> That's why I want to discuss the most ergonomic way of handling this sort of situation... Like, I've got this great config-to-code generation pipeline and I've got functions that can take an array of analog "ChannelState"s or a traditional key matrix and automatically update (Keyberon's) "layers" (in-place) with the correct events... But _is that the right way to do it_? That's what I need to figure out: What are the...
<re_irc> ... best practices?
<re_irc> <riskable> The biggest pain in the ass when it comes to keyboard firmwares is _configuring the damned things_, haha. They also don't do a good job of _being flexible_. If your hardware works just a _tad_ different than the hard-coded assumptions then it becomes even worse!
<re_irc> <dirbaio> maybe it'll be easier to make it a lib and letting the user wire things up in Rust code
<re_irc> <riskable> The architecture I've come up with is:
<re_irc> - "src/bin/<some board>/"
<re_irc> - "src/lib/<various support modules>"
<re_irc> The "various support modules" are the code that handle generating keyboard/mouse/whatever events (Keyberon's version of "CustomEvent" too). You can pass in the state of the hardware and they'll figure out what's currently pressed/not pressed and whether or not something needs to apply key repeat or send a macro or whatever the user's configured. It's up to the board-specific "" to gather the state of the _physical_...
<re_irc> ... hardware into the "PerhipheralState" variable before passing it along into the various keyboard, encoder, infrared, lighting, and display modules' "update_state()" functions.
<re_irc> <riskable> * handles
<re_irc> <riskable> It's also the job of the board-specific "" to handle _scheduling_ of the hardware checks. Like, the support modules will update "layers" but the "" still needs "send_keyboard_report()" and "send_mouse_report()" functions (though they can be mostly copy/pasted)
<re_irc> <riskable> I don't know if this the best (or even a _good_) way to do it
<re_irc> <762spr> TimSmall: Oh sweet! That might be a little over my head at this point, I am still very much a beginner but it is very encouraging to hear!
<re_irc> <riskable> I think this way is more flexible than the QMK model where you have _one_ option for defining keys (rows/columns in a matrix) and have to write write dozens of .c and header files to finagle your hardware into the QMK operating model (attaching zillions of functions to zillions of specific-named callbacks). My way you just write a normal "" and simply call "update_state()" for each kind of hardware your board...
<re_irc> ... uses (e.g. keyboard and maybe a rotary encoder). You can do whatever TF you want in "" which means it can support any hardware that Rust supports--and you don't have to wait for the firmware framework to add support for a particular architecture.
<re_irc> <riskable> So it's kind of like how dirbaio suggested: Make a lib and the user will "wire things up in Rust". Except I want to be able to have a great big directory of supported boards in "src/bin" 😄 and a very easy configuration file format that non-developers can use to configure their keyboard to behave the way they want.
<re_irc> <riskable> I also want to make it possible to have "apps" that can be run via the display and lighting features that many keyboards have these days. So if you add the "calculator" app to the config and say, bind a keystroke to launch it the end user using my firmware can have that feature without having to know how to code Rust. I'm not sure how to make that work yet though hehe
<re_irc> <riskable> Maybe moving to an event stream based architecture like K900 suggested is a good way to handle something like that: When the user "executes" the "app" an event will get fired that changes the operating mode of the keyboard from running the "keyboard" app to running say, the "calculator" app. Hmmm
<re_irc> <riskable> I know it's like... "All software eventually evolves into an OS" or whatever that quote is haha
<re_irc> <riskable> > "Every program attempts to expand until it can read mail. Those programs which cannot so expand are replaced by ones which can." -Zawinski's Law of Software Envelopment
<re_irc> <riskable> So I guess I need to make sure that the necessary framework is in place to make keyboards that can read mail 😁👍
neceve has quit [Ping timeout: 246 seconds]
<re_irc> <marmrt> broke: using keyboards to write email
<re_irc> woke: using keyboards to read email
cr1901_ is now known as cr1901
<re_irc> <jannic> Is it ok to require a process running on the host supporting the mail reading, or should the keyboard implement USB networking and an IMAP client?
<re_irc> <K900> Tunnel IMAP over TCP in USB
<re_irc> <K900> Duh
<re_irc> <dirbaio> ethernet-over-usb :P
<re_irc> <riskable> Oh I was planning on implementing RFC2549 protocol by placing a perch and an NFC tag reader at the back of the keyboard along with a little food tray 👍
fabic has quit [Ping timeout: 256 seconds]
<re_irc> <riskable> Ooh there's a new version of "usbd-hid"! Added get/set_protocol support and support for boot keyboard protocol (finally!) 👍
neceve has joined #rust-embedded
<re_irc> <Phil Markgraf> Does this list have any rules about posting jobs? (I am the hiring manager and a hands-on developer in the team.)
<re_irc> <adamgreig> it's encouraged, and if you tweet rustembedded you can get RT'd too
<re_irc> <adamgreig> so long as they are related to embedded rust, anyway!
<re_irc> <Phil Markgraf> I am looking for an embedded Rust engineer for my team at where we are making a breakthrough medical device for precisely delivering therapies into difficult to access locations in the body. We use Mob Programming and support remote work (in the U.S.) Apply at: or reach out to me directly at:
<re_irc> <riskable> I'm looking at the "usb-device" code ("", specifically) and it has this:
<re_irc> pub fn interrupt<D: EndpointDirection>(&self, max_packet_size: u16, interval: u8)
<re_irc> #[inline]
<re_irc> -> Endpoint<'_, B, D>
neceve has quit [Remote host closed the connection]
<re_irc> <pmc_bn44> Hello folks! I am new to embedded systems and embedded Rust and wondering if anyone is familiar with the Ferrous Systems embedded training 2020 (linked below). I am doing the training for beginners and having trouble with getting xtask to to work! If anyone is willing to help, I can describe the problem further. Please and thank you!
Foxyloxy has joined #rust-embedded