fabic has joined #rust-embedded
rjframe has quit [Remote host closed the connection]
rjframe has joined #rust-embedded
rjframe has quit [Remote host closed the connection]
rjframe has joined #rust-embedded
tokomak has joined #rust-embedded
rjframe has quit [Quit: Leaving]
<re_irc> <@m​etajack:m​atrix.org> Is there something I'm missing about static mut? I have a static mut FOO: [u8; 8] = [0x1, 0x2, ...], but if I try to read it I get garbage. Do static mut's not get initialized?
<re_irc> <@o​rvi:m​atrix.org> metajack: I can't reproduce your problem, are you reading inside an unsafe block?
<re_irc> <@m​etajack:m​atrix.org> The static mut is stored in SRAM1, does that matter/
<re_irc> <@o​rvi:m​atrix.org> I'm not sure, just built a small test to try it out
* re_irc @o​rvi:m​atrix.org is new to embedded stuff
<re_irc> <@d​irbaio:m​atrix.org> yes, static muts are supposed to be initialized before `main`
<re_irc> <@o​rvi:m​atrix.org> maybe something else is touching the memory region where you store FOO?
<re_irc> <@m​etajack:m​atrix.org> `#[link_section = ".sram1_bss"] static mut FOO: [u8; 8] = [0x1, ...];` definitely reads as garbage unless I explicitly write it.
<re_irc> <@d​irbaio:m​atrix.org> `cortex-m-rt` does this
<re_irc> <@d​irbaio:m​atrix.org> ah you're using a custom link section?
<re_irc> <@m​etajack:m​atrix.org> Yes, to do DMA I have to put the buffers there
<re_irc> <@d​irbaio:m​atrix.org> cortex-m-rt initializes `.data` by copying from flash and zerofills `.bss`
<re_irc> <@m​etajack:m​atrix.org> If i do the MaybeUninit dance, that appears to make things work. So I assume static initializers just don't work in that area of memory?
<re_irc> <@d​irbaio:m​atrix.org> it doens't know about `.sram1_bss`, so it won't initialize it
<re_irc> <@d​irbaio:m​atrix.org> (you should name it `.sram1_data` btw. `bss` is for zerofilled stuff)
<re_irc> <@d​irbaio:m​atrix.org> this is the code in question https://github.com/rust-embedded/cortex-m-rt/blob/master/asm.S#L55-L79
<re_irc> <@m​etajack:m​atrix.org> I was basing the off of https://en.wikipedia.org/wiki/Data_segment which seems to disagree with you. Although if you look up BSS on wikipedia it also disagrees with this.
<re_irc> <@d​irbaio:m​atrix.org> 🤷‍♂️
<re_irc> <@d​irbaio:m​atrix.org> .text = program code, in flash
<re_irc> <@d​irbaio:m​atrix.org> .bss = zero-initialized statics. zerofilled on startup
<re_irc> <@d​irbaio:m​atrix.org> .uninit = truly uninitialized data
<re_irc> <@d​irbaio:m​atrix.org> .data = initialized statics, in ram. copied from flash on startup
<re_irc> <@d​irbaio:m​atrix.org> if you create new section names cortex-m-rt won't initialize them for you in any way, you have to do it yourself
<re_irc> <@m​etajack:m​atrix.org> I can't seem to get this to not crash: https://gist.github.com/metajack/9c62566415f8ceaf095d677e59cdcca1
<re_irc> <@m​etajack:m​atrix.org> I can read out the first field (reg_addr_ reliably, but accessing the whole thing just fails.
<re_irc> <@m​etajack:m​atrix.org> It seems really random if it works or not. Sometimes it compiles fine and works every time, and sometimes it compiles badly I guess and fails every time. I must be missing something.
<re_irc> <@r​yan-summers:m​atrix.org> metajack: Multiple link sections for RAM need custom startup code in the runtime ot initialize them. Check out https://github.com/quartiq/stabilizer/blob/master/src/hardware/setup.rs#L148-L180 for how we initialize ITCM
<re_irc> <@b​arafael:m​atrix.org> Hmm. I need a small board with i2c, Bluetooth, and WiFi, that can be used with Rust. Nrf52 doesn't have WiFi. And then there are bl602, esp32s2 and esp32c3, which I know little about but they look good except they are all very early. And then there is stm32wb55. What other options do you think are there and...
<re_irc> ... which do you recommend?
<re_irc> <@b​arafael:m​atrix.org> Try be clear, I don't need WiFi and Bluetooth at the same time. Just need WiFi, and additional Bluetooth as a (build time) alternative would be useful.
fabic has quit [Ping timeout: 255 seconds]
neceve has joined #rust-embedded
<re_irc> <@h​untc:m​atrix.org> barafael: I'm fully expecting something from Nordic at some point. :-) https://www.nordicsemi.com/News/2020/11/Nordic-Semiconductor-expands-into-WiFi
<re_irc> <@e​ldruin:m​atrix.org> metajack: The driver does that automatically for you. You just need to send the arrays with the values and that's it. See for example: [here](https://github.com/eldruin/pwm-pca9685-rs/blob/e24868f48f2eecc41b7c6a5d356eb9fa6a4a6e8f/src/channels.rs#L94)
SomeWeirdAnon has joined #rust-embedded
fabic has joined #rust-embedded
<re_irc> <@a​damgreig:m​atrix.org> this looks cool, just spotted on r/rust: https://github.com/absw/loadstone, especially the configuration gui in egui: https://absw.github.io/loadstone/loadstone_front/published_app/
<re_irc> <@r​yan-summers:m​atrix.org> 32kb is a bit on the larger end for _really_ small devices, but even then, I probably would be avoiding rust on things like MSP430s.
<re_irc> <@r​yan-summers:m​atrix.org> Does it use generic traits to allow descriptions for arbitrary devices? That'd be really cool
<re_irc> <@r​yan-summers:m​atrix.org> E.g. you impl the trait and boom, got a bootloader
<re_irc> <@a​damgreig:m​atrix.org> something like that, it seems, though all the traits are via their own custom HAL https://github.com/absw/loadstone/blob/main/src/ports/stm32f412/bootloader.rs
<re_irc> <@r​yan-summers:m​atrix.org> Looks like they use macros instead
fabic has quit [Ping timeout: 276 seconds]
fabic has joined #rust-embedded
<re_irc> <@l​achlansneff:m​atrix.org> dirbaio: I want to say I strongly agree here. Embedded rust has an opportunity to invent a shiny future for embedded programming — let's make it simple to use.
fabic has quit [Ping timeout: 256 seconds]
fabic has joined #rust-embedded
fabic has quit [Ping timeout: 276 seconds]
<re_irc> <@f​irefrommoonlight:m​atrix.org> I'd like to add that a clear, concise API isn't just to make things friendly for new users: it makes code eaiser to read, write, and maintain
<re_irc> <@u​bik:m​atrix.org> Question: what's the state of Rust on the ESP32?
<re_irc> <@f​irefrommoonlight:m​atrix.org> A wifi NRF would be great
GenTooMan has quit [Ping timeout: 272 seconds]
<re_irc> <@r​yan-summers:m​atrix.org> ub|k: Check out https://github.com/MabezDev/rust-xtensa - it's still somewhat complicated, but I believe there's a lot of people doing it
<re_irc> <@r​yan-summers:m​atrix.org> I don't think Rust has first-class support for xtensa CPUs yet, hence the custom fork
<re_irc> <@u​bik:m​atrix.org> Thanks!
<re_irc> <@u​bik:m​atrix.org> Are there any STM32 devboards which compete with ESP32? I mean WiFi + BLE and cheap?
<re_irc> <@f​irefrommoonlight:m​atrix.org> I don't know of any stm32s that have Wifi
GenTooMan has joined #rust-embedded
<re_irc> <@r​yan-summers:m​atrix.org> Maybe see if you can find something under https://www.st.com/en/microcontrollers-microprocessors/stm32-wireless-mcus.html
<re_irc> <@r​yan-summers:m​atrix.org> Although WiFi is generally a big ask for a microcontroller
<re_irc> <@r​yan-summers:m​atrix.org> Super power hungry and complex do not go well with small, power efficient, and cheap
<Darius> there are quite a few STM32s with wireless
<Darius> not sure they do wifi though, might only be BLE/Zigbee/etc
<re_irc> <@f​irefrommoonlight:m​atrix.org> Stm32WB has BT, Zigbee, and Thread. WL has LoRa etc
<re_irc> <@f​irefrommoonlight:m​atrix.org> Fairly certain those are the only ones
<re_irc> <@f​irefrommoonlight:m​atrix.org> The simplest option may be UART to ESP32
<re_irc> <@b​urrbull:m​atrix.org> therealprof @ada: We need to do something about stm32f1xx. The repo is dying.
<re_irc> <@u​bik:m​atrix.org> pricey
fabic has joined #rust-embedded
<re_irc> <@g​rantm11235:m​atrix.org> > Some SPIs can work with 8-bit *and* 16-bit words. You can overload this trait with different `Word` types to allow operation in both modes.
<re_irc> <@g​rantm11235:m​atrix.org> Are there any SPIs that allow you to use 8-bit and 16-bit words without doing any reconfiguration in between?
<re_irc> <@a​damgreig:m​atrix.org> what do you mean, without any reconfiguration in-between?
<re_irc> <@g​rantm11235:m​atrix.org> Without modifying a control register
<re_irc> <@a​damgreig:m​atrix.org> how would it know if you wanted 8 or 16, just by the width of the access to the data register?
<re_irc> <@a​damgreig:m​atrix.org> the stm32 spi peripherals vary but generally the data frame size is set in a config register and the size of the DR access determines how many words are loaded into the FIFO
<re_irc> <@a​damgreig:m​atrix.org> but that means in practice you could set it to 8-bit mode, and if you do an 8-bit write to DR, it adds one 8-bit word to the FIFO, and if you do a 16-bit access to DR, it adds two 8-bit words and sends them back-to-back, which has the same effect as a single 16-bit transfer
<re_irc> <@a​damgreig:m​atrix.org> so I guess in practice it would look like being able to do either 8 or 16 bit transfers depending only on the access width to DR
<re_irc> <@a​damgreig:m​atrix.org> what do you want it for?
<re_irc> <@a​damgreig:m​atrix.org> (I would have thought for the e-h trait the implication is that the SPI is reconfigured when you call `write` with a different mode, typically, though)
<re_irc> <@g​rantm11235:m​atrix.org> I am considering making a PR that changes the the e-h traits to use an associated word type instead of a type parameter, I'm trying to figure out if that would cause any problems
<re_irc> <@a​damgreig:m​atrix.org> ah, got it
<re_irc> <@a​damgreig:m​atrix.org> I would say you almost always expect to reconfigure to change word length
<re_irc> <@a​damgreig:m​atrix.org> and you can always transfer more shorter words...
<re_irc> <@a​damgreig:m​atrix.org> can you have associated const generics?
<re_irc> <@a​damgreig:m​atrix.org> would be nice to support lengths beyond 8/16/32
<re_irc> <@g​rantm11235:m​atrix.org> You could define newtypes like `struct U9{inner: u16}`
<re_irc> <@a​damgreig:m​atrix.org> as part of e-h? seems kinda messy compared to just a usize if you can get away with it somehow, idk
<re_irc> <@a​damgreig:m​atrix.org> maybe not worth it for the very rare non-multiple-of-8 use case
<re_irc> <@g​rantm11235:m​atrix.org> There have been a few proposals for adding arbitrary size integers to rust, but nothing has really gone anywhere
<re_irc> <@a​damgreig:m​atrix.org> yea, I guess i was wondering if you could use a const generic somehow but perhaps it doesn't make sense
<re_irc> <@a​damgreig:m​atrix.org> hard to know what inner size to use for it too
<re_irc> <@a​damgreig:m​atrix.org> like, what goes in the return position...
<re_irc> <@a​damgreig:m​atrix.org> oh well
<re_irc> <@g​rantm11235:m​atrix.org> Why does `nb::spi::FullDuplex` have separate read and write methods instead of just a single `transfer(&mut self, word: Word) -> nb::Result<Word, Self::Error>`
<re_irc> <@a​damgreig:m​atrix.org> huh, the `blocking` one has transfer
<re_irc> <@g​rantm11235:m​atrix.org> Would it make sense to rearrange e-h to be peripheral-type -> blocking-or-nb -> trait? `nb::spi::FullDuplex` would become `spi::nb::FullDuplex`
<re_irc> <@g​rantm11235:m​atrix.org> And `nb::spi::Mode` would become just `spi::Mode`
dcz_ has joined #rust-embedded
<re_irc> <@a​damgreig:m​atrix.org> I will put that on the agenda for today's meeting in 20min :P
<dcz_> hi folks! is there an easy way to modify/override linker scripts coming from a dependency crate? my project depends on riscv-rt, but I'd like to have a place where I can store "calibration data" and stuff
<re_irc> <@a​damgreig:m​atrix.org> you should be able to just put your own link.x in your crate root and it will get used
<re_irc> <@d​isasm-ewg:m​atrix.org> dcz_: Sure, just copy it under a different name and use it in .cargo/config
<dcz_> that's surprisingly easy, thanks
tokomak has quit [Read error: Connection reset by peer]
<dcz_> one more question: what are the static libs inside the bin/ directory and why are they always linked in without being compiled?
<dcz_> (unless I'm reading build.rs wrong)
<re_irc> <@a​damgreig:m​atrix.org> they're prebuilt static libs that contain the initialisation code from https://github.com/rust-embedded/riscv-rt/blob/master/asm.S
jds has joined #rust-embedded
<re_irc> <@a​damgreig:m​atrix.org> you need a risc-v compiler (riscv64-unknown-elf-gcc) to assemble them yourself, and rust stable doesn't have any way to build assembly yet (requires nightly features), so for convenience they're pre-built and linked
<dcz_> oh, thanks
<re_irc> <@a​damgreig:m​atrix.org> oh my god, what was it in the end?
<edm> i applied the hiroshima method rather than the scientific one
<edm> so I'm not completely sure
<dcz_> although I'm surprised that having an assembler is not an assumption for building the crate, prebuilt binaries are ugly
<re_irc> <@a​damgreig:m​atrix.org> dcz_: yea.. the solution eventually is for rustc to be able to build it for you, so once the relevant features are stabilised I expect the crates will swap to that, and in the meantime this is the closest approximation
<dcz_> I'm not a cargo expert, but building will already fail for sys crates if some native dependency isn't present, so I expected analogous behaviour here
<re_irc> <@g​rantm11235:m​atrix.org> I saw some activity in the `asm!` tracking issue recently, it might be coming soon
<re_irc> <@a​damgreig:m​atrix.org> sadly I think we'll need global_asm for the rt crates
<agg> edm: hah, perfect, well i'm glad it worked eventually
<edm> anyway i deleted any existing versions of rust-analyzer and any suspicious environment variables and just built it back from scratch and it all works so that's enough not-engineering for now
<re_irc> <@m​etajack:m​atrix.org> eldruin: Does it leave that mode on always, so I can depend on that mode after I destroy()?
<re_irc> <@m​etajack:m​atrix.org> ryan-summers: I'm unclear what you mean here. I have a custom section `.sram1_bss` at RAM_D2 (0x30000000). I understand after yesterday's conversations that that memory is uninitialized regardless of what the Rust initializer does to the static mut. The DMA examples all use MaybeUninit::uninit() for the...
<re_irc> ... initializer, then manually initialize the memory in their code, adn then use it. When I attempt to do that, the program crashes most of the time.
<re_irc> <@m​etajack:m​atrix.org> Is there something special I need to do to use that memory?
<re_irc> <@g​rantm11235:m​atrix.org> adamgreig: Can you add https://github.com/rust-embedded/embedded-hal/pull/295 to the agenda too?
<re_irc> <@a​damgreig:m​atrix.org> already done
<re_irc> <@a​damgreig:m​atrix.org> oh, but I haven't linked it so you can't tell, lol
<re_irc> <@a​damgreig:m​atrix.org> anyway yep it's on there
j`ey has joined #rust-embedded
<re_irc> <@g​rantm11235:m​atrix.org> 😊
<re_irc> <@a​damgreig:m​atrix.org> @room meeting time again! agenda is https://hackmd.io/hFF3u7YkRr6AbzzfdRLJRA, please add anything you'd like to announce or discuss and we'll start in 5 minutes :)
<re_irc> <@e​ldruin:m​atrix.org> metajack: It is not changed so if you run an operation which enables it and destroy it later, it will stay on
<re_irc> <@f​irefrommoonlight:m​atrix.org> GrantM11235: Not happening.
<re_irc> <@a​damgreig:m​atrix.org> ok, let's start!
<re_irc> <@a​damgreig:m​atrix.org> I don't remember anything to announce from this week, does anyone have anything?
<re_irc> <@a​damgreig:m​atrix.org> if not, I will just drop this link from our twitter to the embedded-text 0.5 beta release https://twitter.com/bugadani/status/1413881352869617671
<re_irc> <@a​damgreig:m​atrix.org> ok, let's get into the embedded-hal stuff, there's a few things afterwards so I'll move on if we take too long
<re_irc> <@a​damgreig:m​atrix.org> first up was a very quick controversy-bomb that GrantM11235 dropped a few minutes ago suggesting putting `nb`, `blocking` etc inside the peripheral modes...
<re_irc> <@a​damgreig:m​atrix.org> so we'd have `spi::nb::Write` instead of `nb::spi::Write`
<re_irc> <@a​damgreig:m​atrix.org> of course this isn't even a PR yet so more soliciting some quick feedback I guess
j`ey has left #rust-embedded [#rust-embedded]
<re_irc> <@f​irefrommoonlight:m​atrix.org> I prefer his approach without giving it much thought. Feels like it puts the more important division (what peripheral are you using?) deeper
<re_irc> <@l​achlansneff:m​atrix.org> Yeah, I'm for that
<re_irc> <@a​damgreig:m​atrix.org> perhaps you should go for a PR then GrantM11235!
<re_irc> <@f​irefrommoonlight:m​atrix.org> You will have to answer the question "Why is this worth a change that breaks most e-h code?". Put that in the PR text
<re_irc> <@a​damgreig:m​atrix.org> the next item is another new PR for e-h about making the Word sizes be associated types instead of generic parameters, https://github.com/rust-embedded/embedded-hal/pull/295/files
<re_irc> <@a​damgreig:m​atrix.org> it's only just been opened so mostly just highlighting that it exists if anyone wants to have a look and leave thoughts on the PR
<re_irc> <@a​damgreig:m​atrix.org> (maybe worth adding a description with a justification etc, GrantM11235?)
<re_irc> <@r​icharddodd:m​atrix.org> I don't think this is good? Currently you can implement the same trait for multiple different data types. The new signature only allows 1 type.
<re_irc> <@r​icharddodd:m​atrix.org> I might be missing something.
<re_irc> <@f​irefrommoonlight:m​atrix.org> So, this lets you specify word on each method call (eg read or write) instead of once for the periph?
<re_irc> <@g​rantm11235:m​atrix.org> adamgreig: Yeah, I was in a bit of a rush to submit this before the meeting
<re_irc> <@r​icharddodd:m​atrix.org> GrantM11235: what's your goal with the PR?
<re_irc> <@g​rantm11235:m​atrix.org> firefrommoonlight: This is the current status quo, I don't think it is a good idea
<re_irc> <@f​irefrommoonlight:m​atrix.org> I haven't hit a use case that would require a flexible word, so won't comment further on this
<re_irc> <@r​icharddodd:m​atrix.org> With the current signature, you can implement the trait multiple times for different `Word`s, which offers polymorphism. If you force the implementer to choose the word type at impl, the user can no longer select from a choice: they have to use the one the implementer chose.
<re_irc> <@g​rantm11235:m​atrix.org> richarddodd: Impl'ing `Write<u8>` and `Write<u16>` at the same time would require the driver to keep track of what word size the hardware is configured for and/or reconfigure the hardware each time the write method is called
<re_irc> <@d​irbaio:m​atrix.org> "flexword isn't used often" is not a justification to remove it though
<re_irc> <@d​irbaio:m​atrix.org> the question is what do we *gain* by removing it
<re_irc> <@r​icharddodd:m​atrix.org> Ahh GrantM11235 so you're arguing that there is a soundness problem because some periphs need to keep track of word size? I thought most of the time the impl would turn it into a byte array before sending anyways.
<re_irc> <@g​rantm11235:m​atrix.org> dirbaio: Is it ever used? (honest question)
<re_irc> <@d​irbaio:m​atrix.org> GrantM11235: if the spi driver doesn't want to do that, it could have different types Spi8 and Spi16 and impl Write<u8> for Spi8 and Write<u16> for Spi16
<re_irc> <@d​irbaio:m​atrix.org> EH doesn't mandate that the hal spi HAS to implement both
<re_irc> <@r​icharddodd:m​atrix.org> Personally I've only ever used the u8 implementation, so I shouldn't take part in this discussion further I think.
<re_irc> <@d​irbaio:m​atrix.org> with the current approach it's up to HAL authors to choose: impl both on the same driver type, or have two driver types
<re_irc> <@d​irbaio:m​atrix.org> with the proposed approach with ATs, only "have two driver types" is possible
<re_irc> <@a​damgreig:m​atrix.org> right, so the HAL can still provide eg Spi8 and Spi16, but not just Spi that can do either
<re_irc> <@a​damgreig:m​atrix.org> but if they do impl Write u8 and u16 for Spi, then the write() method would need to check which type it's being used with and configure the peripheral appropriately, every call
<re_irc> <@r​icharddodd:m​atrix.org> Is there any case of using u16 that can't be handled by `to_ne_bytes`?
<re_irc> <@d​irbaio:m​atrix.org> imo the current approach is "strictly better": it adds more options
<re_irc> <@a​damgreig:m​atrix.org> it's half as efficient to use u8 as u16 if you can use u16, measuring by number of memory transfers
<re_irc> <@d​irbaio:m​atrix.org> these "more options" are arguably not very useful yep, but they don't *hurt*
<re_irc> <@r​icharddodd:m​atrix.org> adamgreig: Ahh I'm thinking of DMA and arrays, hadn't considered individual bytes.
<re_irc> <@a​damgreig:m​atrix.org> even for DMA it's half as efficient, the DMA will need to make twice the number of transfers
<re_irc> <@t​halesfragoso:m​atrix.org> Just check the guidelines, generic type for traits that make sense to implemente for different types and associated types for the ones that don't
<re_irc> <@a​damgreig:m​atrix.org> *well, maybe the DMA can read u32 from memory and write u8 to the SPI, so it's not too bad, but that's a trickier configuration
<re_irc> <@t​halesfragoso:m​atrix.org> So it seems clear that generic types are the "correct" option
<re_irc> <@r​icharddodd:m​atrix.org> thalesfragoso: if a trait has an associated type, you can make other trait bounds that rely on it (e.g. `<T as IntoIterator>::Item`)
<re_irc> <@a​damgreig:m​atrix.org> do any HALs impl for multiple sizes today?
<re_irc> <@t​halesfragoso:m​atrix.org> You can still do Spi<Word: SomeTrait>
<re_irc> <@r​icharddodd:m​atrix.org> thalesfragoso: Yeah I just had that thought. I'm gonna shut up. :P
lambda has joined #rust-embedded
<re_irc> <@g​rantm11235:m​atrix.org> adamgreig: Also, do any drivers use `Write<u8> + Write<u16>`?
<re_irc> <@e​ldruin:m​atrix.org> I remember needing `Write<u12>` or so once
<re_irc> <@e​ldruin:m​atrix.org> but that is obviously not available. I think I just did not write the driver
<re_irc> <@a​damgreig:m​atrix.org> it looks like stm32h7xx-hal does impl for u8, u16, and u32, though I can't immediately tell what happens if you call write with different types one after another
<re_irc> <@a​damgreig:m​atrix.org> ah, there the Spi driver is generic over its type
<re_irc> <@a​damgreig:m​atrix.org> so Spi<u8> impls Write<u8> and etc
<re_irc> <@a​damgreig:m​atrix.org> and thus only configures once, at configuration-time, but could also turn itself into another type at runtime if you wanted to change config
<re_irc> <@a​damgreig:m​atrix.org> that seems pretty reasonable too
<re_irc> <@g​rantm11235:m​atrix.org> Note that my proposal would still allow HALs to use an API like this:
<re_irc> <@g​rantm11235:m​atrix.org> ```rust
<re_irc> <@g​rantm11235:m​atrix.org> ''`
<re_irc> <@g​rantm11235:m​atrix.org> multi_word_spi.as_u16().write(0x1234)?;
<re_irc> <@g​rantm11235:m​atrix.org> multi_word_spi.as_u8().write(0x00)?;
<re_irc> <@a​damgreig:m​atrix.org> (so, the driver doesn't need to keep track or check what sort of write() is being called)
<re_irc> <@d​irbaio:m​atrix.org> again, question: what do we *gain* by making this change?
<re_irc> <@r​icharddodd:m​atrix.org> Could the advantages/disadvantages of both approaches be written up on the PR? Then it would be easier to make the decision how to proceed?
<re_irc> <@d​irbaio:m​atrix.org> to me it seems that we're losing the flexibility of impling Write<u8> and Write<u16> at the same time, but not *gaining* anything in exchange
<re_irc> <@a​damgreig:m​atrix.org> let's move on for now, GrantM11235 perhaps you could update the PR description with a summary of the motivation and we can revisit next week?
<re_irc> <@a​damgreig:m​atrix.org> thanks!
<re_irc> <@a​damgreig:m​atrix.org> I wanted to revisit a few of the older e-h PRs as well and see if we can get them moving again, as a few have built up
<re_irc> <@a​damgreig:m​atrix.org> eldruin, I don't know if you have any thoughts about the buildup or if it would be useful to have more hal team members? I appreciate the last month or two have been quite hal heavy
<re_irc> <@a​damgreig:m​atrix.org> "quite heavy" being the nice way to say everyone else has been throwing big PRs at you guys for weeks :P
<re_irc> <@d​irbaio:m​atrix.org> 😇
fabic has quit [Ping timeout: 272 seconds]
<re_irc> <@a​damgreig:m​atrix.org> Lachlan Sneff, for removing the defaults in https://github.com/rust-embedded/embedded-hal/pull/289, does https://github.com/rust-embedded/embedded-hal/pull/289#issuecomment-873756479 help address the issue?
<re_irc> <@d​irbaio:m​atrix.org> I'm in favor of removing the Defaults too
<re_irc> <@d​irbaio:m​atrix.org> but for a different reason: it establishes the `nb` traits as the True Traits and the `blocking` traits as derived ones
<re_irc> <@d​irbaio:m​atrix.org> it encourages HAL writers to impl only the `nb` traits and base everything off that
<re_irc> <@l​achlansneff:m​atrix.org> Well, I guess so
<re_irc> <@l​achlansneff:m​atrix.org> I'd prefer the async traits to be the true ones to be honest, but in the meantime, `nb` is better
<re_irc> <@d​irbaio:m​atrix.org> and `nb` is incompatible with lots of nice stuff, such as DMA impls
<re_irc> <@d​irbaio:m​atrix.org> and we might even want to deprecate `nb` in the future
<re_irc> <@e​ldruin:m​atrix.org> adamgreig: Quite a few have been filed and some also merged, yes. still they require some "meditation time" / back-and-forth so it's not like we can move at a much higher speed
<re_irc> <@b​urrbull:m​atrix.org> dirbaio: I'm also not opposite to this
<re_irc> <@e​ldruin:m​atrix.org> removing the defaults is fine with me
<re_irc> <@e​ldruin:m​atrix.org> but ryan was the one more involved there
<re_irc> <@e​ldruin:m​atrix.org> I'll leave my opinion in the issue
<re_irc> <@d​irbaio:m​atrix.org> also the "Default" trick makes for not very nice docs
<re_irc> <@t​herealprof:m​atrix.org> Removing `Default` works for me, too.
<re_irc> <@d​irbaio:m​atrix.org> Ideally that should show `Spi` impls `embedded_hal::blocking::spi::Transfer`, but it doesn't
<re_irc> <@a​damgreig:m​atrix.org> ok, let's move on from e-h for now, please feel free to leave some more comments on the PR threads where you have thoughts :)
<re_irc> <@a​damgreig:m​atrix.org> fairly quick mention of some cortex-m-rt stuff, I've opened two new PRs for a 0.6.15 backport release with some bug fixes and for a 0.7.0 release with all the breaking changes since 0.6.11 (!)
<re_irc> <@a​damgreig:m​atrix.org> the 0.6.15 I think is fairly easy but if there are any other non-breaking bug fixes people would like included, please mention on the PR, https://github.com/rust-embedded/cortex-m-rt/pull/329, and I'll include them
<re_irc> <@a​damgreig:m​atrix.org> otherwise let's hopefully get that released soon
<re_irc> <@a​damgreig:m​atrix.org> 0.7.0 is a bit harder and I'd especially appreciate any feedback on what open issues we'd like to fix before 0.7, if any: https://github.com/rust-embedded/cortex-m-rt/pull/330
<re_irc> <@a​damgreig:m​atrix.org> I think probably the resource stuff is out of scope for 0.7 unless someone is very hot to fix it somehow, either by providing it in another crate or reworking it in c-m-rt (or working through the draft PR for the new syntax)
<re_irc> <@d​irbaio:m​atrix.org> just remove it ☠️
<re_irc> <@a​damgreig:m​atrix.org> just removing it without a replacement isn't popular with therealprof
<re_irc> <@a​damgreig:m​atrix.org> and it's fair enough, plenty of people are using it in one way or another
<re_irc> <@d​irbaio:m​atrix.org> I'd argue the replacement is RTIC...
<re_irc> <@d​irbaio:m​atrix.org> or a static mut with unsafe
<re_irc> <@a​damgreig:m​atrix.org> perhaps there's room for a simpler replacement for the key concept of "resource available for just one interrupt context"
<re_irc> <@a​damgreig:m​atrix.org> but yea, maybe static mut with unsafe is that replacement
<re_irc> <@a​damgreig:m​atrix.org> ok, last up, richarddodd do you want to talk about your topic?
<re_irc> <@r​icharddodd:m​atrix.org> Yeah slightly different from the other stuff, I just wanted to say that I think embedded Rust could be very big, because it makes embedded very accessible (at least to me).
<re_irc> <@r​icharddodd:m​atrix.org> And personally I like prose (with figures/code/etc) as a way to communicate what work is going on and allow other people to spot opportunities to get involved.
<re_irc> <@l​achlansneff:m​atrix.org> I agree. Embedded rust is how I'm getting my foot in the door of embedded development
<re_irc> <@r​icharddodd:m​atrix.org> You can do the best work in the world, but if nobody knows, it doesn't mean anything :)
<re_irc> <@r​icharddodd:m​atrix.org> Yeah embedded Rust makes embedded accessible for non-embedded programmers. It's a gateway into all the electronics and IC goodness.
<re_irc> <@r​icharddodd:m​atrix.org> This is partly because they embedded book is a great intro. But there are less resources for intermediate-level stuff.
<re_irc> <@r​icharddodd:m​atrix.org> Yeah so it's very easy for me to say "I think there should be more literature about embedded Rust, someone else write it". I don't think we can expect people to have infinite time. Just wanted to draw attention to the fact that it's very appreciated.
<re_irc> <@a​damgreig:m​atrix.org> if anyone ever wants to write or cross-post a blog post on the rust-embedded blog they'd be very welcome to, as well
<re_irc> <@r​icharddodd:m​atrix.org> I might have a go at writing something and posting it on urlo/reddit and seeing what the response is.
<re_irc> <@l​achlansneff:m​atrix.org> richarddodd: Continuing on that, I think it should be a goal of embedded rust to make using rust on embedded devices as obvious and straightforward as possible.
<re_irc> <@r​icharddodd:m​atrix.org> Cheesy mode on: the goal of Rust is to empower everyone to be a systems programmer. I think it can also empower everyone to be an embedded programmer.
<re_irc> <@m​etajack:m​atrix.org> More examples would definitely help. See my recent forays into trying to use i2c or DMA
<re_irc> <@l​achlansneff:m​atrix.org> Something I've been thinking about in that area is whether examples could be device agnostic somehow.
<re_irc> <@r​icharddodd:m​atrix.org> I'd also argue that non-embedded people learning about embedded will make them better overall programmers, even if they carry on doing something else in their day job.
<re_irc> <@m​etajack:m​atrix.org> I mean, i bought a discovery board, and I'm happy to use that to learn, so more advanced stuff with a known board config seems fine.
<re_irc> <@l​achlansneff:m​atrix.org> Lachlan Sneff: Things like micropython are almost completely device agnostic for the simple stuff.
<re_irc> <@m​etajack:m​atrix.org> I have to say though, the extremely better toolchain of cargo/rust has made embedded stuff far easier than any other time I've ever tried.
<re_irc> <@r​icharddodd:m​atrix.org> What I liked about using Rust for embedded is that you can start at the bottom: most things like audrino want you to use a C lib. With embedded rust you can start with the MMIO, which is the way I prefer to learn.
<re_irc> <@k​evlan:m​atrix.org> I have been looking for ideas for topics for a Youtube channel I have started. If there are specific sensors or interfaces that people think are popular I could definitely try and do some videos on getting started with them. So far my channel has been playing with power supplies but I have a couple weeks until I...
<re_irc> ... get boards back to finish that series...
<re_irc> <@m​etajack:m​atrix.org> eldruin 's PCA9865 thing is pretty good starter component I think. one you can communicate with i2c, it has a very easy protocol. sort of 1 step beyond turn on/off the led.
<re_irc> <@r​icharddodd:m​atrix.org> As well, I think people in embedded rust deserve recognition for some really great work.
<re_irc> <@m​etajack:m​atrix.org> I've been around Rust a long time, and I was quite surprised to dip into this corner of the world and find it so nice :)
<re_irc> <@m​etajack:m​atrix.org> Yes, exactly. I think adafruit has one as well.
<re_irc> <@r​icharddodd:m​atrix.org> So that's all I wanted to do: bring communication up in a vague way and get people thinking about it. Thanks.
<re_irc> <@a​damgreig:m​atrix.org> thank you!
<re_irc> <@a​damgreig:m​atrix.org> everybody please write blog posts about how great embedded rust is :D
<re_irc> <@a​damgreig:m​atrix.org> and with that let's end the meeting for this week, thanks for attending everybody!
<dcz_> is whoever maintains this crate pingable here? there seem to be outstanding pull requests, and I also have some questions https://github.com/riscv-rust/gd32vf103xx-hal
<dcz_> namely, is backup_domain really a stub or if I'm missing something
<re_irc> <@e​ldruin:m​atrix.org> That would be disasm
jds has left #rust-embedded [WeeChat 1.9.1]
<dcz_> it would be cool to contribute, but not if my changes are to go unreviewed
<re_irc> <@m​etajack:m​atrix.org> Ok, so I’ve got a trimmed down example of the memory use errors I’m running into. I’m trying to put a static mut buffer in SRAM where the DMA controller can read it, but my program is crashing when I try to access the memory. It sometimes works and mostly crashes, though the behavior seems that it works...
<re_irc> ... find in gdb with openocd and fails with probe-run most of the time. Here’s the code: https://gist.github.com/metajack/6243ae52a6a46e9732643713790792f0
<re_irc> <@m​etajack:m​atrix.org> I’ve also tried it in sram2 and sram3 with the same result, and if I don’t put it in a specific link section it also has the same behavior.
<re_irc> <@d​irbaio:m​atrix.org> I don't see anything obviously wrong with that code :S
<re_irc> <@d​irbaio:m​atrix.org> How does it crash? HardFault?
<re_irc> <@d​irbaio:m​atrix.org> You can try the steps here to try to figure out what is making the MCU angry https://interrupt.memfault.com/blog/cortex-m-fault-debug
lambda has left #rust-embedded [WeeChat 3.2]
<re_irc> <@m​etajack:m​atrix.org> It usually disconnects the usb probe immediately
<re_irc> <@m​etajack:m​atrix.org> so I don’t see anything about why it’s crashing
<re_irc> <@d​irbaio:m​atrix.org> ah
<re_irc> <@d​irbaio:m​atrix.org> then maybe it's working correctly but you don't see it?
<re_irc> <@d​irbaio:m​atrix.org> could be some rcc/clock/power issue? maybe you need to turn on SRAM1 explicitly?
<re_irc> <@m​etajack:m​atrix.org> How do I turn it on? :)
<re_irc> <@m​etajack:m​atrix.org> Compiling fieldtest v0.1.0 (/Users/jack/src/fieldtest)
<re_irc> <@m​etajack:m​atrix.org> Running `probe-run --chip STM32H750IBKx target/thumbv7em-none-eabihf/debug/examples/sram1_test`
<re_irc> <@m​etajack:m​atrix.org> Finished dev [unoptimized + debuginfo] target(s) in 0.29s
<re_irc> <@m​etajack:m​atrix.org> (HOST) INFO flashing program (59.99 KiB)
<re_irc> <@m​etajack:m​atrix.org> In case you wanted to see what running it does on my machine.
<re_irc> <@d​irbaio:m​atrix.org> USB communication error, wow?
<re_irc> <@n​fd:c​ybre.space> Maybe that error could use a tad more detail
<re_irc> <@h​anno:b​raun-odw.eu> `W` being the word size (`u8` or `u16`) in this case. However, `W` is also part of the type itself, so I think the same approach would work, if the word size were an associated type.
neceve has quit [Ping timeout: 276 seconds]
<re_irc> <@l​achlansneff:m​atrix.org> How do you all feel about `Read` and `Write` being in `core` vs. being in `alloc`?
<re_irc> <@g​rantm11235:m​atrix.org> The only reason they would be in `alloc` is `io::Error`, right?
<re_irc> <@l​achlansneff:m​atrix.org> Yep, and some methods that take `Vec` and `String`.
<re_irc> <@l​achlansneff:m​atrix.org> Which were in the trait, not an extension trait, unfortunately
<re_irc> <@d​irbaio:m​atrix.org> If they require a lloc they're still not going to get widely used in embedded
<re_irc> <@l​achlansneff:m​atrix.org> That's honestly true, despite that small amount of alloc not really mattering
<re_irc> <@m​etajack:m​atrix.org> nfd: Is there a way to get more detail and figure out what’s going wrong?
<re_irc> <@n​fd:c​ybre.space> metajack: i hope so 😬
<re_irc> <@n​fd:c​ybre.space> seems something weird is going on with the stacghk thou
<re_irc> <@d​irbaio:m​atrix.org> Lachlan Sneff: Well, it does matter because you still need to have a heap even if you're going to use it "very little"
<re_irc> <@d​irbaio:m​atrix.org> I don't want a heap at all
<re_irc> <@n​fd:c​ybre.space> metajack, what device are you using?
<re_irc> <@m​etajack:m​atrix.org> stm32h750ib (as part of the daisy field)
<re_irc> <@d​irbaio:m​atrix.org> Adding a heap to a project opens the door to some dependency using `alloc` without you noticing. If you have no heap, trying to use such a dependency would fail to build, so you have the guarantee nothing uses alloc at all
<re_irc> <@n​fd:c​ybre.space> metajack: hmm, well, https://www.st.com/resource/en/reference_manual/rm0433-stm32h742-stm32h743753-and-stm32h750-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf pp. 135 might be of note. i don't know which sram segments you're mentioning map to what here, but it definitely seems possible to have power...
<re_irc> ... settings that would leave some of the chunks of sram powered off
<re_irc> <@n​fd:c​ybre.space> brings a tear to my eye, a 3319 page pdf...
dcz_ has quit [Ping timeout: 256 seconds]
<re_irc> <@l​achlansneff:m​atrix.org> dirbaio: Does embassy use heap?
<re_irc> <@d​irbaio:m​atrix.org> Nope!
<re_irc> <@l​achlansneff:m​atrix.org> Oh, fascinating.
<re_irc> <@l​achlansneff:m​atrix.org> How does the executor store multiple tasks then?
<re_irc> <@d​irbaio:m​atrix.org> tasks are statically allocated, spawn is fallible
<re_irc> <@d​irbaio:m​atrix.org> if you do `#[task] async fn foo()`, it statically-allocates one `Task<F>` where `F` is the future type for `async fn foo()`
<re_irc> <@d​irbaio:m​atrix.org> this means only one instance of `foo` can be running at a time max
<re_irc> <@d​irbaio:m​atrix.org> `spawner.spawn(foo())` will fail if `foo` is already running
<re_irc> <@d​irbaio:m​atrix.org> if `foo` finishes it, you can respawn it
<re_irc> <@d​irbaio:m​atrix.org> you can also do `#[task(pool_size=4)]`, in which case up to 4 instances of task `foo` can run concurrently
<re_irc> <@l​achlansneff:m​atrix.org> That's super interesting
<re_irc> <@l​achlansneff:m​atrix.org> Kinda similar to rtic
<re_irc> <@d​irbaio:m​atrix.org> all tasks go in `static`s
<re_irc> <@d​irbaio:m​atrix.org> if you have too many or they're too big, the linker will detect it at compile time that they don't fit in RAM
neceve has joined #rust-embedded
zBeeble has joined #rust-embedded
<zBeeble> how (or to whom) do I submit a new platform resource file?
<re_irc> <@t​herealprof:m​atrix.org> Hm, what is a platform resource file?
<re_irc> <@m​etajack:m​atrix.org> nfd: It's AHB SRAM1, which is in the D2 domain. I can get the same crash if I don't locate the static mut in SRAM too, just normal ram like anything else. Ie, just remove the `#[link_section(...)]` attribute and it still happens.
<re_irc> <@n​fd:c​ybre.space> are you ending up in HardFault or is USB just quietly dying/stack getting corrupt otherwise?
<re_irc> <@n​fd:c​ybre.space> might be worth writing a HF handler that just holds one specific LED strong to find out
<re_irc> <@m​etajack:m​atrix.org> I'll try that in a sec. Right now I'm trying to switch to semihosting to see if it has the same problem.
<re_irc> <@d​irbaio:m​atrix.org> Is there a "simple" heap-less queue somewhere?
<re_irc> <@d​irbaio:m​atrix.org> heapless has spsc::Queue and mpmc::Queue but they're not simple at all, they use atomics and stuff
<re_irc> <@t​herealprof:m​atrix.org> https://docs.rs/heapless/0.7.3/heapless/binary_heap/index.html ?
<re_irc> <@d​irbaio:m​atrix.org> FIFO queue, not priority queue
<re_irc> <@m​etajack:m​atrix.org> wow semihosting is slow, but seems to work
<re_irc> <@t​herealprof:m​atrix.org> dirbaio: You didn't say that. 😉
<re_irc> <@m​etajack:m​atrix.org> At this point, it appears to be a problem with probe-run or rtt_target. If I run the code in gdb it's always fine.
<re_irc> <@d​irbaio:m​atrix.org> I just need a heapless equivalent of `VecDeque`, where both enqueue/dequeue require `&mut self`
<re_irc> <@t​herealprof:m​atrix.org> metajack: Friends don't let friends use semihosting...
<re_irc> <@d​irbaio:m​atrix.org> I guess I should PR it
<re_irc> <@d​irbaio:m​atrix.org> there's `arraydeque` and `fixed_vec_deque`.. not const generics though
<re_irc> <@m​etajack:m​atrix.org> nfd: How do I do that? All the peripherals are consumed in the main code. Do I need to steal them and stash them for hte HardFault handler?
<re_irc> <@n​fd:c​ybre.space> i don't think you usually worry about having to give things back from HardFault
<re_irc> <@t​herealprof:m​atrix.org> metajack: In a HardFault handler you're pretty much at the end of the road anyway. You can do whatever you want.
<re_irc> <@m​etajack:m​atrix.org> I mean getting them into HardFault
<re_irc> <@n​fd:c​ybre.space> yeah just unsafely steal them however you want
<re_irc> <@m​etajack:m​atrix.org> Ok, I just looked at the code. I assume steal only worked bfore they got removed from teh Option. Didn't realize it just gives you another copy.
<re_irc> <@t​herealprof:m​atrix.org> You can also manually obtain the pointer into the peripheral and just bang away at the registers.
<re_irc> <@t​herealprof:m​atrix.org> I think the less dependency on a HAL/PAC you have in your HF handler, the more likely it is that there're no bad sideeffects which could cause it to fail.
<re_irc> <@m​etajack:m​atrix.org> with this:
<re_irc> <@m​etajack:m​atrix.org> #[exception]
<re_irc> <@m​etajack:m​atrix.org> // turn on the led after HardFault
<re_irc> <@m​etajack:m​atrix.org> fn HardFault(ef: &ExceptionFrame) -> ! {
<re_irc> <@m​etajack:m​atrix.org> oh, that should have been steal() in the first one.
<re_irc> <@t​herealprof:m​atrix.org> Yes, can't `take()` twice.
<re_irc> <@t​herealprof:m​atrix.org> But again, I'd be careful with this kind of code. The more complex it is, the more likely it is that it won't work/fault again which is bad, especially in that situation.
<re_irc> <@m​etajack:m​atrix.org> Changed it to steal, the led does not turn on.
<re_irc> <@d​irbaio:m​atrix.org> "USB Communication Error" doesn't mean the target chip has crashed
<re_irc> <@m​etajack:m​atrix.org> Yes, I think that was what we were trying to determine :)
<re_irc> <@m​etajack:m​atrix.org> It appears the chip is not crashing
<re_irc> <@t​herealprof:m​atrix.org> Initialise the GPIO in your init code. Then just enable it using the most lowlevel way.
<zBeeble> is re_irc piping in some other chat channel
<zBeeble> ?
<zBeeble> a platform resource file configures rust to run on a platform --- there is a collection of them in the source tree.
<re_irc> <@t​herealprof:m​atrix.org> metajack: Like `(*GPIOC::ptr()).odr.write(|w| w.odr7().high())`
<re_irc> <@t​herealprof:m​atrix.org> zBeeble: Gotcha. Those have to be PRed to the rust project directly.
<re_irc> <@m​etajack:m​atrix.org> Ok, so I put led blinking in the loop at the end of main. Before I do the memory code, I flash the led for 1s then turn it off. I run the code, it gets a usb error, and the led is blinking on and off repeatedly.
<re_irc> <@m​etajack:m​atrix.org> So the code successfully started, it did the memory stuff, I got the usb error, and the code kept going to start blinking the led.
<re_irc> <@m​etajack:m​atrix.org> Ok, so if I take rprintln! out of hte loop, it doesn't crash. I thought it was supposed to be in a mode where overflowing the buffer was no big deal?
<re_irc> <@m​etajack:m​atrix.org> However, even though it doesn't crash, the contents of my struct is all zeros, despite initializing it to have some nonzero data in it.
<re_irc> <@m​etajack:m​atrix.org> I've removed all the memory stuff I'm doing. The only code left is:
<re_irc> <@m​etajack:m​atrix.org> let mut bytes = [0u8; 65];
<re_irc> <@m​etajack:m​atrix.org> for (idx, b) in bytes.iter().enumerate() {
<re_irc> <@m​etajack:m​atrix.org> rprintln!("{}: {:02x}", idx, b);
neceve has quit [Ping timeout: 246 seconds]
<re_irc> <@m​etajack:m​atrix.org> I've also now tested NoBlockTrim and BlockIfFull mode, as well as with 4096 size buffers, and the crash happens regardless of the settings, though different amount of RTT output happen on each run.
<re_irc> <@d​irbaio:m​atrix.org> sounds like a probe issue
<re_irc> <@d​irbaio:m​atrix.org> probe-run is still on probe-rs 0.10, there's been lots of fixes to probe-rs lately
<re_irc> <@m​etajack:m​atrix.org> So I should install from github main branch?
<re_irc> <@m​etajack:m​atrix.org> oh, nm, I once again didn't notice run,rs difference.
<re_irc> <@d​irbaio:m​atrix.org> try `cargo install --git https://github.com/knurling-rs/probe-run`
<re_irc> <@d​irbaio:m​atrix.org> yep
<re_irc> <@m​etajack:m​atrix.org> USB error gone. thank you :)
<re_irc> <@d​irbaio:m​atrix.org> wohoo
starblue3 has quit [Ping timeout: 272 seconds]
starblue3 has joined #rust-embedded
<re_irc> <@m​etajack:m​atrix.org> OMG, the DMA worked!
<re_irc> <@m​etajack:m​atrix.org> Now I can blast all 16 leds via DMA.
<re_irc> <@m​etajack:m​atrix.org> Apparently my changes to the hal crate were enough to enable DMA. I'll submit a PR for those.
creich has quit [Quit: Leaving]
<agg> zBeeble: yes, it's bridging the Matrix room #rust-embedded:matrix.org
<agg> IRC users appear as virtual matrix users, but to avoid maintaining 300 connections to the IRC server, all the Matrix users come through as one bot
<agg> except for some cursed reason my own messages don't come through to matrix, but I run the bridge... go figure?
<re_irc> <@d​khayes117:m​atrix.org> If I have a structure that implements several methods, and I need to use the same methods and structure format for 4 different unique structures...how do I handle that with minimal code duplication?
<re_irc> <@d​khayes117:m​atrix.org> IE. Each struct is named for the register that it will contain, Pmpcfg0, Pmpcfg1, Pmpcfg2.. , and each one should implement the same methods ?
<re_irc> <@d​irbaio:m​atrix.org> make a Reg trait and impl them for all
<re_irc> <@d​irbaio:m​atrix.org> or maybe do like svd2rust does, which is having a `Reg<T>` and the "shared" methods are on Reg
<re_irc> <@d​khayes117:m​atrix.org> So I would create a trait that can handle a generic type, the different structs in this case, and the trait would hold the methods then impl the trait on each struct? I have never used traits and I just learned about what they actually are lol.