_whitelogger has joined ##stm32-rs
<adamgreig-m> and then make "gpioa_pins" struct that has take(gpioa)->self or something, and do that for timers, ADCs, whatever else you wanted to do this with...
<dirbaio[m]> uberstructs aren't that unergonomic, the user takes out whatever they need
<dirbaio[m]> singleton crate can't depend on the PAC
<dirbaio[m]> a pac major bump would be a singleton major bump
<dirbaio[m]> and singletons major bump breaks EVERYTHING
<adamgreig-m> also one design goal is to allow the same singleton to be reused by different PACs/HALs/etc
<dirbaio[m]> and (almost) all PAC bumps are major bumps
<wallacejohn[m]> dirbaio: Ideally there wouldn't be any PAC major bumps once everything is implemented according to RMs, right? Just adding new devices, I guess.
<dirbaio[m]> even fixing a tiny typo in a reg name is a major bump
<dirbaio[m]> and these will happen, we can't get it perfect from day 0
<adamgreig-m> also HALs (which would already depend on the -peripherals crate) could wrap it for convenience
<adamgreig-m> so users only need to directly depend on their HAL, if they're only using one
<dirbaio[m]> well
<dirbaio[m]> in embassy i'm trying to not expose PAC types on the public api
<dirbaio[m]> so a pac major bump is not a hal major bump :)
<adamgreig-m> yea, but this is -peripherals not -pac
<adamgreig-m> the HAL can't avoid exposing -peripherals types in the API, right?
<dirbaio[m]> yeah, hal exposes peripheral tyes
<dirbaio[m]> * yeah, hal exposes peripheral types
<dirbaio[m]> not pac types
<adamgreig-m> yea, I'm saying the HAL could provide convenience methods to take() the peripherals for you, so the user only needs to depend on the HAL and not also peripherals (directly)
<dirbaio[m]> so if there's a pac major bump, the hal update sthe pac dep then fixes usages of whatever reg was renamed and that's it, but doesn't need a major bump itself
<firefrommoonligh> Re owning periph + timer channels. This is what EH traits etc expect, and I don't like it for STM32, since it does'nt coincide with the hardware layout. You're forced into raw pointers. Good for generic abstraction, but poor fit for owning-regblocks model
<adamgreig-m> yea I'm totally onboard with the HAL not exposing the PAC types
<adamgreig-m> firefrommoonlight: yea, hopefully with the new PACs that would be less of an issue though
<adamgreig-m> since the HAL would only have unsafe register access anyway, it could know "if I own tim2_ch2 I can safely write to the tim2.ccr2 register without locking"
<firefrommoonligh> Re exposing PACs: No need for a re-export etc. Just let the user import the PAC and use it. This also is a vote for not owning things like RCC, since then your HAL etc does'nt play nice with others
<adamgreig-m> though there is some downside in that the hals are presumably now filled with unsafe blocks, lol
<firefrommoonligh> Great re new PAC model. I think the abstraction concept is good; my objection is implementation with current hardware / PAC
<dirbaio[m]> I find it more annoying to have to use unsafe but only sometimes
<firefrommoonligh> I don't know enough about memory safety to comment on the dangers of that approach
<dirbaio[m]> ie only if using .bits() or only if stealing because the pac's ownership model doesn't match
<firefrommoonligh> If I can trust that the HAL author who knows more about memory didn't screw things up, then that's fine. I haven't heard of problems with HAL GPIO and PWM, which use raw pointesr
<adamgreig-m> yea, I see the annoyance, hopefully HALs can find some way to not require unsafe in literally every single function though
<firefrommoonligh> (although for the purpose of abstracting over concepts that don't map to STM32 reg setup)
<dirbaio[m]> hals wouldn't require unsafe from the user
<adamgreig-m> yea, just a question of how much unsafe they'd need internally
<dirbaio[m]> a lot ðŸĪ·â€â™‚ïļ
<adamgreig-m> I guess one option is for the new PACs to provide an optional safe access to registers if you give them the &mut owned singleton from -peripherals
<adamgreig-m> but meh.....
<dirbaio[m]> more unsafe yes
<dirbaio[m]> but less brain cycles spent on "do I need unsafe?"
<adamgreig-m> I'm not sure that's the brain cycles we need to optimise, lol
<adamgreig-m> the compiler tells you p quick if you needed it and didn't have it
<adamgreig-m> vs working out if you actually have exclusive access to this memory address or not
<dirbaio[m]> before: "Do I need unsafe? maybe if i'm stealing, or if i'm going to use .bits() to workaround lack of arrayified fields etc"
<dirbaio[m]> now: "Do I need unsafe? yes"
<adamgreig-m> I can certainly imagine finding more accidental rmw races in hals when all their methods need to be unsafe
<adamgreig-m> given a lot of peripherals do not need splitting, maybe the pacs should allow safe access if you give them the right owned singleton from peripherals
<adamgreig-m> that still solves all your nrf issues since you couldn't have spim and spis at the same time
<dirbaio[m]> how do you do that theN?
<adamgreig-m> the PAC needs to know the type (if any) from -peripherals that allows safe access to the whole peripheral
<dirbaio[m]> svd2rust would need to know about the "TWI0, TWIM0, TWIS0, SPI0, SPIM0, SPIS0 are really the same peripheral, you can only use 1 at a time" thing, for example
<dirbaio[m]> yeah
<dirbaio[m]> so you can no longer generate a PAC from a SVD
<dirbaio[m]> you need the SVD + the peripherals crate + the mapping
<adamgreig-m> I assumed we were already moving away from that with the yaml thing
<adamgreig-m> I mean, you can, it just defaults to only unsafe access
<adamgreig-m> this is an incremental improvement if present
<dirbaio[m]> dunno in my mind the yaml thing was going to be stm32-specific
<adamgreig-m> and what, it would generate an svd for the family-wide thing that went into svd2rust?
<adamgreig-m> I was expecting a common yaml format for some new PAC generator (based on svd2rust or otherwise) so we can support the [cfg] stuff etc
<adamgreig-m> how would you do the cfg idea without it?
<dirbaio[m]> if the SVDs are very consistent and accurate like in nrf, the effort to do a metapac isn't worth it imo
<wallacejohn[m]> dirbaio: Can you still call it svd2rust at that point? ðŸĪŠ
<firefrommoonligh> TIe-in to the TSP split... I appreciate how the Rust compiler protects me from the more subtle sorts of memory bugs, but don't need it to prevent me from using the wrong pin for my I2C or something, when it's spelled out in the user manual, and will be an obvioustroubleshooting step if you do misconfig it.
<adamgreig-m> so the yamls is not stm32-rs specific, or it is but it generates a generic IR?
<adamgreig-m> is the IR not yaml?
<firefrommoonligh> I'm happy with Rust keeping me from getting us-eafter-free or UB race conditions without making sure I picked the right pin
<dirbaio[m]> ah you're asking hard questions :S
<adamgreig-m> firefrommoonlight: yea, this is another somewhat controversial thing where different people want different things
<adamgreig-m> a lot of people are prototyping with dev boards and report that the compile-time pin assignment checking is extremely helpful and useful
<adamgreig-m> especially when they're new to the chip, and the datasheets are not very approachable
<adamgreig-m> otoh, some people are just using a custom PCB that's already designed, they can't change pins anyway, they've checked everything when they did the schematic, and it's too late for the compiler to help them regardless, so they don't want to faff with all the typestate pin stuff, just configure the spi peripheral please
<firefrommoonligh> It's easy for a new user (That was me!) to conflate existing conventions with requirements. Someone more experienced starting Rust might not making this error, and realize there are choices
<dirbaio[m]> - peripheral yaml = regblocks + fieldsets + enums
<dirbaio[m]> - chip yaml = "peripheral X, addr Y, regblock Z, irqs 1, 2, 3"
<dirbaio[m]> you can assemble 1 chip yaml + 10 peripheral yamls into an IR which is then translated into Rust code
<dirbaio[m]> or mabye into a chip-specific SVD in the future!
<adamgreig-m> ok, so the YAML isn't stm32-rs specific at that point?
<dirbaio[m]> not for now
<firefrommoonligh> agg: that explanation makes sense. I think the core is different people have different use cases
<adamgreig-m> firefrommoonlight: the stmh7xx-hal seems like a nice solution where you have new and new_unchecked and the pin types aren't stored
<adamgreig-m> dirbaio: so the chip YAML can also say "periphral X, addr Y, regblock Z, irqs 1, 2, 3, owned singleton U"
<firefrommoonligh> After going back adn forth on that (Originally I wanted to adopt that based on your mentioning it before), I decied to completely skip it
<dirbaio[m]> I mean
<adamgreig-m> if it doesn't say the last part, it doesn't have any safe interface, only unsafe, but if it does say it, the generated PAC provides safe access if you can provide U
<firefrommoonligh> Adds so much complexity to both HAL and user code
<dirbaio[m]> the tool would support workflow with yamls, or workflow straight from svds
<adamgreig-m> firefrommoonlight: so you only have new_unchecked, as it were? the peripheral drivers just never check or configure the pins?
<dirbaio[m]> and projects would pick the best workflow for them
<adamgreig-m> dirbaio: sure, that doesn't affect it, the straight-from-svd case would just never get any safe access
<firefrommoonligh> Yep. Just `new`
<firefrommoonligh> That's correct
<dirbaio[m]> ah so the tool also supports generating both PACs based on a peripherals crate, and a standalone PACs?
<dirbaio[m]> maybe! ðŸĪ·â€â™‚ïļ
<adamgreig-m> firefrommoonlight: that's what I'd use personally since my projects tend to fall into the second camp, but I can see the appeal of the compile-time pin checking for people who aren't familiar with the datasheet etc
<adamgreig-m> or it always generates standalone PACs but optionally can add a dependency on a -peripherals crate to use the types from it to provide a safe API
<firefrommoonligh> I do think both options is the best way, but the fact I'm doing multi-family makes it not worht the difficulty creating and maintaining it
<adamgreig-m> the safe API can come later, it's entirely additive, but it would let a lot of HALs avoid any unsafe code
<firefrommoonligh> Agree. Could bolt it on, or let someone else do it
<adamgreig-m> (I would argue it should allow writing any value to bits anytime, to remove the "sometimes unsafe" you have now)
<dirbaio[m]> would safe and unsafe apis mean the pac would have ~2x the generated code amount?
<dirbaio[m]> for regs+fieldsets at least?
<adamgreig-m> not sure but it seems like you could avoid it
<adamgreig-m> maybe you do end up with a safe and an unsafe method for each register access at least, but one would presumably just call the other and be inlined, hopefully not a huge hit :/
<dirbaio[m]> dunno, i'm not sure it's worth the extra complexity
<dirbaio[m]> there's also the "you can turn off RAM without unsafe" proble
<dirbaio[m]> * there's also the "you can turn off RAM without unsafe" problem
<adamgreig-m> so you don't do it for those types of peripherals like RCC and DMA
<dirbaio[m]> more extra input you have to manually give to svd2rust :D
<adamgreig-m> it's less input
<adamgreig-m> because you just don't tell it about an owned peripheral type for those ones
<dirbaio[m]> and maybe you do want an owned peripheral for some regs and not others in the same peripheral
<dirbaio[m]> like
<adamgreig-m> yea, it doesn't work in those cases (like timers or whatever)
<adamgreig-m> but there's a lot of peripherals where it does make sense to just own the whole thing
<dirbaio[m]> allow safe access to all powermanagement stuff except trning off RAM
<adamgreig-m> usually power management is going to be accessed by lots of different drivers anyway though
<firefrommoonligh> Yes - don't own RCC!
<adamgreig-m> meh, just spitballing here, a bit concerned about how every single hal function ends up needing to include an unsafe block, but still drawn to PACs not providing safe access
<dirbaio[m]> I think "safe vs unsafe" shouldn't be solved at the pac layer
<dirbaio[m]> too complex, requires lots of human input
<dirbaio[m]> and more stuff to learn for newcomers
<dirbaio[m]> "why does reading X's regs work differently than Y's??"
<adamgreig-m> at least "all are unsafe to access, but in a few cases you can prove you have safe access and then they're safe" is simpler than "you have to own all registers to get safe access, there's a very weird unsafe ptr() thing as an escape hatch, but even then sometimes it's unsafe for nonsense reasons"
<dirbaio[m]> true
<adamgreig-m> but in any event can also come later
<dirbaio[m]> but "all register access is unsafe" is even simpler :D
<adamgreig-m> can't argue with that, lol
<dirbaio[m]> pac = unsafe register acces
<dirbaio[m]> hal = building safe abstractions on top of the pac
<dirbaio[m]> where are the safe abstractions built? in the hal
<dirbaio[m]> not "mostly in the hal, but some in the pac with help from the peripherals crate"
<adamgreig-m> perhaps the HALs can themselves build a safe register interface to the PAC using the -peripherals
<adamgreig-m> if they want to avoid unsafe in all the functions
<adamgreig-m> in which case there'd be no need to have it in the pac at all
<dirbaio[m]> yea
<dirbaio[m]> most already do something like that, for gpio for example
<dirbaio[m]> nrf has private safe methods to access gpio regs that should really be unsafe but whatever
<dirbaio[m]> I see the PACs kinda like bindgen bindings
<dirbaio[m]> bindgen simply makes all fns unsafe because it can't know which are safe and which aren't
<dirbaio[m]> its job is generating a binding, not building a safe abstraction
<wallacejohn[m]> dirbaio: I agree.
<dirbaio[m]> it's not that bad.. less bad than I expected =D
<dirbaio[m]> in total there's like 5-6 regblock variants :C
<firefrommoonligh> Nice
<firefrommoonligh> I'm working on a saner way to handle RCC enabling/reset in a HAL
<firefrommoonligh> Struggling with the macros now though :/
<firefrommoonligh> `no method named `tim15rst found... for APB1RSTR1... TIM15: (tim15, Two)... in this macro invocation`
<firefrommoonligh> Like bro, I don't know how you're on that match arm
<dirbaio[m]> the macro emits both arms
<dirbaio[m]> so both arms have to compile correctly
<firefrommoonligh> Is that some quantum superposition thing?
<dirbaio[m]> it's not related to macros
<dirbaio[m]> stuff inside that if has to compile correctly even if it's never executed
<dirbaio[m]> later on the compilation process the optimizer sees it's never executed and removes it
<dirbaio[m]> but the code is still parsed etc
<dirbaio[m]> your match is like that if
<firefrommoonligh> Oh shit you'r eright
<dirbaio[m]> you need more macro magic to not even emit the wrong branch from the macro :D
<firefrommoonligh> I had a paste system before, but the macro construction was too nutty
<firefrommoonligh> This one just looks like `TIM14: (tim14, ONE)`, but may not be able to make this work
<dirbaio[m]> macros themselves are "like matches"
<dirbaio[m]> macro_rules! apb_reset {
<dirbaio[m]> }
<dirbaio[m]> * hold on
<dirbaio[m]> something like that
<dirbaio[m]> should work
<firefrommoonligh> Oh sweet
<firefrommoonligh> Haven't used macro matches like that before
<dirbaio[m]> it's the way to do kindof an "if" or "match" in compiletime macro expansion
<dirbaio[m]> super whacky but super cool :D
<firefrommoonligh> Where would you call that from?
<firefrommoonligh> (Btw, I think I have a way to make paste work with this too...)
<dirbaio[m]> from your main macro, `apb_reset!($apb, $tim)`
<dirbaio[m]> if $apb is 1 it'll emit the code from the first branch, the 2nd otherwis
<dirbaio[m]> * if $apb is 1 it'll emit the code from the first branch, the 2nd otherwise
<firefrommoonligh> Sweet. Do you know if there's some othe rway to separate the arms? Getting an unexpected expression on line 7
<dirbaio[m]> exact syntax of my snippet may be off, check with the manual :S
<firefrommoonligh> *`^ no rules expected this token in macro call`
<firefrommoonligh> sweet
<firefrommoonligh> Works now! The only dif was ; instead of ,
<dirbaio[m]> I think it's `;` after the `{}`s
<dirbaio[m]> lol
<firefrommoonligh> wait nvm, getting same error as original
<firefrommoonligh> Nvm works just bad c+p
<firefrommoonligh> A bit repetitive, but works with most STM32s, and the macro calling it relatively clean
<firefrommoonligh> Thanks for all the help
<dirbaio[m]> paste AND cfg_if AND macro matches
<dirbaio[m]> fun!
<firefrommoonligh> Maybe once you get your PAC out we won't need so much magic
<dirbaio[m]> hope so :S
<firefrommoonligh> l4, l5, and g4 all agree on how to do it, but everything else is diff :/
<firefrommoonligh> I guess the fs are buddies
<firefrommoonligh> Actually, now that I think about it, the apb2 timer code can all be simplified: It's H7 vs the world
<dirbaio[m]> haven't looked at RCC yet...
<firefrommoonligh> APB1 is totally diff though
<dirbaio[m]> but I don't think i'll be unify that one heh
<firefrommoonligh> *sry G0 is the odd one out on apb2
<dirbaio[m]> how are you going to handle chips where the regblocks are completely different?
<dirbaio[m]> for example gpio regs on f1 have a "different shape"
<dirbaio[m]> eh but maybe similar enough that #[cfg] works
<firefrommoonligh> Depends on how different
<dirbaio[m]> i'm wondering if there's some instance where
<dirbaio[m]> it's better to write a completely new driver
<firefrommoonligh> I haven't hit a roadblock yet, across 7 families
<dirbaio[m]> and pull in one driver or the other
<firefrommoonligh> Actually... The answer is separate modules when it happens. For example, F4 SPI is totally diff from anything newer, so I have a sep module
<firefrommoonligh> Or the clocks are split into 3 modules.
<firefrommoonligh> (Although can probably merge 2 of them... H7 will always have a sep clocks mod)
<firefrommoonligh> *oops it's F4 I2C
<dirbaio[m]> oh yeah that was exactly my question
<dirbaio[m]> like i2c vs i2c_f4 right?
<firefrommoonligh> yep!
<firefrommoonligh> Even with RCC, G0, G4, L4, and L5 all share a clocks module, and they're not THAT different from f3 and f4
<dirbaio[m]> makes sense, f4 is the only i2cv1 in your families
<firefrommoonligh> Bookmarked - that's great
<dirbaio[m]> why is dma_f3 special?
<firefrommoonligh> That v3 must be comparible for I2C with V2; The code I'm using on my L4 project is based on the H7xx hal's i2c
<firefrommoonligh> Oh... No idea. I haven't messed with DMA. It's a straight C+P from l4 to get serial working
<firefrommoonligh> Serial and DMA are the most lacking parts right now
<dirbaio[m]> ah OK
<dirbaio[m]> that table is lifted from the chibiOS makefiles btw
<dirbaio[m]> I haven't checked everything
<firefrommoonligh> It's surpising f4 has the v2 DMa
<dirbaio[m]> they link in a different driver .c file depending on the versions
<dirbaio[m]> checked i2c, uart, gpio and yes, it seems to correspond to "fundamentally different" regblocks
<dirbaio[m]> (vs same regblock with extra additions)
<firefrommoonligh> This also explains why I couldn't get ADC to work on f4
<dirbaio[m]> there's FIVE adc versions lol
<dirbaio[m]> I think adc v1 and v2 should be swapped
<dirbaio[m]> (table is sorted by release date)
<firefrommoonligh> That fits
<firefrommoonligh> I'm surprised G4 doesn't have the newest ADC. It's one of their newest ones, and has perhaps the most robust ADC functionality of any
<dirbaio[m]> ðŸĪ·â€â™‚ïļ
<dirbaio[m]> lol all F4 svds have `<fpuPresent>false</fpuPresent>`
<dirbaio[m]> lies!!!!
<firefrommoonligh> CortexM4F right...
<firefrommoonligh> I think only the super old ones don't have it
<firefrommoonligh> (Not sure about M0+?)
<dirbaio[m]> g0 is m0+ and doesn't have a fpu
<firefrommoonligh> oh shit
<firefrommoonligh> I guess for $1 each or w/e I can't complain
<disasm[m]> <dirbaio[m] "https://docs.google.com/spreadsh"> Hey! USB on L432 is different from that on F103!
<dirbaio[m]> ðŸĪ·â€â™‚ïļ as I said it's lifted straight from chibios makefiles
<dirbaio[m]> they have a single usbv1 driver
<dirbaio[m]> maybe it's legit wrong or maybe they ifdef it somewhere else
<disasm[m]> Maybe versions represent completely incompatible versions of the peripheral with the same "name"
<peauters[m]> hi all, anyone have any examples of using spi? I'm trying to drive some sk6812 rgbw leds ( they are more or less similar to ws2812bs) and I'm trying to use spi to write the frames for each led
<peauters[m]> ahhhh nice
<adamgreig-m> there are some examples for stm32f0 and stm32f1 here: https://github.com/smart-leds-rs/smart-leds-samples
<peauters[m]> thanks adamgreig
<dirbaio[m]> name: TIM1_BRK_TIM9
<dirbaio[m]> description: "TIM1 Break interrupt and TIM9 global interrupt"
<dirbaio[m]> so you can't use TIM1 and TIM9 independently?? the hell, ST
<adamgreig-m> lol, it doesn't want to be put in your little box :p
<adamgreig-m> you can use them independently except their irqs are ORd together
<dirbaio[m]> how am I supposed to HAL that
<adamgreig-m> yea...
<adamgreig-m> wonder which one is more likely to be useful
<adamgreig-m> another use case for "taking this singleton also takes these other ones"
<adamgreig-m> mutually exclusive singletons :/
<thalesfragoso[m]> Probably TIM9, for the HAL
<dirbaio[m]> embassy has singletons for irqs
<adamgreig-m> TIM1 break is extremely good if you're doing like, motor control or something
<adamgreig-m> can't embassy just fake it?
<thalesfragoso[m]> Yeah, but that probably should be a separate driver
<adamgreig-m> register an irq handler, check both flags, dispatch to them
<thalesfragoso[m]> And then the driver asks for it
<adamgreig-m> yea makes sense
<thalesfragoso[m]> But then you can't use TIM9 if you want break
<thalesfragoso[m]> But hey, you got a lot of timers, come on
<dirbaio[m]> problem with shared irqs is if you only want to use tim1 it starts pulling code for tim9
<adamgreig-m> or you just can't use it with interrupt anyway
<dirbaio[m]> oh and that interrupt is only listed in the TIM1 peripheral
<dirbaio[m]> so we'll have to manually put in the yamls that it's also for TIM9
<dirbaio[m]> I was thinking something like
<dirbaio[m]> for every peripheral, there's interrupts with "functions"
<dirbaio[m]> so map
<thalesfragoso[m]> Also, TIM1 and 8 have more than one interrupt, a bit hard to put abstract over that with other timers .-.
<thalesfragoso[m]> * Also, TIM1 and 8 have more than one interrupt, a bit hard to abstract over that with other timers .-.
<dirbaio[m]> peripheral X has irq 15 for function "overflow", irq 49 for function "break"
<dirbaio[m]> this is actually what devicetree does.. lol
<therealprof[m]> Great, so we're going for devicetree now? 😀
<dirbaio[m]> maybe just datamining zephyr's devicetrees
<dirbaio[m]> don't think they're very complete though
<therealprof[m]> Yeah, only available for select MCUs.
<therealprof[m]> But that doesn't actually seem like the worst of options.
<firefrommoonligh> Isn't that TIM interrupt thing just like with GPIO EXTI all ports on the same line?
<firefrommoonligh> Figure out which one it is in the ISR somehow?
<dirbaio[m]> this one is even more disgusting
<dirbaio[m]> `description: "TIM6 global interrupt, DAC1 and DAC2 underrun error interrupt"`
<adamgreig-m> Lol
<adamgreig-m> TIM6 is earmarked for use as dac timebase
<adamgreig-m> Which is why it doesn't have any output channels
<adamgreig-m> Still a bit gross to combine the irq
<dirbaio[m]> ah, not that horrible then
<thalesfragoso[m]> dirbaio we will need timer register blocks with CCs
<dirbaio[m]> you mean they're missing in the metapac?
<thalesfragoso[m]> Have you decided to go with the super block even if the peripheral doesn't support it ?
<thalesfragoso[m]> I mean, some timers have 1 or zero, which won't work for embassy "rtc"
<thalesfragoso[m]> So if you merge them all into just the common denominator then they won't work for embassy "rtc"
<dirbaio[m]> there's this for now
<dirbaio[m]> the 1ch/2ch ones are missing
<thalesfragoso[m]> The 16bits only seem to have 2 CCs in that docs
<thalesfragoso[m]> Which is a bit limiting, since a good amount have 3 or 4
<thalesfragoso[m]> Btw, looking at the docs alone is a bit hard to know the range of the `n` argument, I had to look at the source to find one assert, maybe we want that on the docs ?
<dirbaio[m]> was missing CCRx, just fixed
<dirbaio[m]> <thalesfragoso[m] "Btw, looking at the docs alone i"> yep, 100%
<dirbaio[m]> it has the 4 CCs
<dirbaio[m]> CCMR contains config for 2 CCs, but it iself is an array of 2, so total 4
<dirbaio[m]> so to configure CCx you can do `regs.ccmr_output(x/2).write(|w| w.set_ocm(x%2, whatever))`
<dirbaio[m]> no macros!
<dirbaio[m]> how do you "disconnect" a gpio?
<dirbaio[m]> just put it back to floating input?
<dirbaio[m]> there's no "disconnected" state?
<thalesfragoso[m]> <dirbaio[m] "there's no "disconnected" state?"> Not really
<dirbaio[m]> ðŸ’Đ
<dirbaio[m]> it's alive! it blinks a LED! :D
<wallacejohn[m]> <dirbaio[m] "how do you "disconnect" a gpio?"> You could use the reset bit in RCC and turn off the clock.
<dirbaio[m]> I see, that's per-port though
<adamgreig-m> I don't think that's different from setting it to a floating input
<adamgreig-m> what would it mean to be any more 'disconnected'?
<dirbaio[m]> on nrf you can disconnect pins, they use less power
<dirbaio[m]> in fact there's no "input or output" mode
<dirbaio[m]> there's a "output enable yes or no" and "input enable yes or no" bits
<wallacejohn[m]> I think turning off the clock to the port is equivalent to disconnecting on NRF, but it's per port as you say.
<dirbaio[m]> for minimum power usage you can set both to no
<adamgreig-m> hmm
<adamgreig-m> you probably want "analog" mode then
<dirbaio[m]> this is for the embassy hal
<adamgreig-m> I would just make it a floating input then, that's the reset state
<dirbaio[m]> when you create an `Output` it configures the pin as output, when you drop it it should "deconfigure" it
<adamgreig-m> if you put the pin into analog mode it disconnects the input buffer from the pin, but afaik the input data register still registers on every clock
<adamgreig-m> meh, depends what deconfigure has to mean, could just leave it too
<adamgreig-m> but input-floating is the reset state anyway
<adamgreig-m> analogue input mode might be slightly lower power, I wonder.
<dirbaio[m]> 👍ïļ
<dirbaio[m]> will do input-floating for now :P
<dirbaio[m]> and just leaving it wouldn't work, the whole point of allowing drivers to borrow peripherals is so they get deconfigured/stopped on drop
<adamgreig-m> sure but does it matter if the pin is left as an output after it's dropped?
<adamgreig-m> you'll still turn it into whatever you need later
<dirbaio[m]> consistency with other drivers like uart/spi/etc
<adamgreig-m> interesting, if set the lock bits on the gpio peripherals it halves the power consumption, and if you're just using AF or analogue mode you can turn off the GPIO clock entirely once it's set
<dirbaio[m]> drop a driver = all the "things" the driver was doing are poof, gone
<adamgreig-m> looks like analogue mode is indeed the lowest power, though for a non-changing input I suspect it's a miniscule difference
<thalesfragoso[m]> <dirbaio[m] "there's a "output enable yes or "> Can you put yes on both ?
<adamgreig-m> sure, but do you reset the spi peripheral when it's dropped?
<adamgreig-m> or just reset it on creation?
<adamgreig-m> like, clear the 'enable' bit, sure
<dirbaio[m]> on nrf it does "disable"
<dirbaio[m]> the equivalent on stm would be disabling it on rcc I guess
<adamgreig-m> but leaving the gpio as output doesn't seem materially different to leaving it as input
<dirbaio[m]> and deconfiguring the pins
<adamgreig-m> you still can't change it since it's been dropped
<adamgreig-m> anyway doesn't really matter either way I guess.
<dirbaio[m]> you can with borrows :D
<thalesfragoso[m]> Input floating is usually the recommended default state
<adamgreig-m> well idk, it might actually be quite surprising if you configured the pin to be an output and then didn't touch it and it ended up dropped and turned back into an input
<adamgreig-m> but I suppose it wouldn't have dropped by accident in that case
<thalesfragoso[m]> <adamgreig-m "well idk, it might actually be q"> Embassy uses drivers for GPIO too
<adamgreig-m> yea, so when you configure it for something else, it turns into whatever else it needs
<thalesfragoso[m]> So the pin is just something you usually can't do much with
<adamgreig-m> it seems slightly surprising that led going out of scope would cause the led to turn off too
<adamgreig-m> but whatever, if anyone cared about what it did they'd just make it not go out of scope at that point I guess
<adamgreig-m> seems like a waste of cpu time configuring it to an input again only to later turn it back into an output when the next person wants to use it, vs just leaving it be?
<thalesfragoso[m]> It's a bit weird, but makes sense, you're dropping the driver, you wouldn't expect it to continue to work
<adamgreig-m> depends what "continue to work" means in the case of a gpio though I guess
<thalesfragoso[m]> I.e. gpio is a bit on the edge of this idea
<dirbaio[m]> yeah with gpios it's very "on the edge"
<thalesfragoso[m]> * Ye, gpio is a bit on the edge of this idea
<dirbaio[m]> but it makes sense for consistency with "big" drivers like uart etc
<dirbaio[m]> you drop an `Uart` instance, it stops driving the TX pin
<dirbaio[m]> so you drop a `Output` instance, it stops driving too
<dirbaio[m]> ðŸĪ·â€â™‚ïļ
<dirbaio[m]> laggy
<thalesfragoso[m]> * Yes, gpio is a bit on the edge of this idea
<adamgreig-m> interesting, the stm32l4 actually reset the gpios to analogue mode instead
<adamgreig-m> reset values for gpio are 0xABFFFFFF, 0xFFFFFEBF, 0xFFFFFFFF, 0x0000000F for A, B, C-G, H, lol
<dirbaio[m]> <thalesfragoso[m] "Can you put yes on both ?"> yes! useful for opendrain. you can drive the line to 0 or not, and when you don't you can use input to see if someone else is driving it to 0 :D
<dirbaio[m]> goddamnit
<thalesfragoso[m]> <adamgreig-m "interesting, the stm32l4 actuall"> Maybe they discovered what you just did
<dirbaio[m]> wow had to refresh the page to stop my messages from reordering randomly