DepthDeluxe__ has quit [Ping timeout: 260 seconds]
DepthDeluxe has joined #rust-embedded
starblue1 has quit [Ping timeout: 252 seconds]
starblue1 has joined #rust-embedded
wes_ has quit [Quit: WeeChat 2.8]
DepthDeluxe has quit [Ping timeout: 260 seconds]
DepthDeluxe has joined #rust-embedded
DepthDeluxe has quit [Ping timeout: 255 seconds]
<re_irc>
< (@korken89:matrix.org)> Does anyone have a recommendation for a thermal receipt printer? I'd like to have it in our test setup to print test results, but there is an army of printers.
<re_irc>
< (@korken89:matrix.org)> I guess any printer with ESC/POS protocol is fine as it's only UART?
<re_irc>
< (@korken89:matrix.org)> Nice, thank you for the code!
<re_irc>
< (@korken89:matrix.org)> No need to publish for me, I'll play around a bit :D
<re_irc>
<henrik_alser> Happy it can be of use :)
<re_irc>
< (@korken89:matrix.org)> What is this "rppal" btw?
<re_irc>
< (@korken89:matrix.org)> Running an RP2040 from a PC?
<re_irc>
< (@korken89:matrix.org)> Ah wait, it seems to be for a "normal" Rasperry PI
<re_irc>
<henrik_alser> Yeah it’s like a hal for raspberry pi :) The rp 400 is pretty handy for testing drivers
<re_irc>
<henrik_alser> +with e-hal trait impls
<re_irc>
<henrik_alser> I have one set up in my lab mostly as an ”interactive html bom” viewer :)
<re_irc>
<henrik_alser> And audio spectrum analyzer
<re_irc>
<henrik_alser> (Using my own adc frontend connected via i2s on the gpio header)
<re_irc>
<henrik_alser> Then i have super high resolution real time fft on fullscreen with Reaper :D
<re_irc>
< (@korken89:matrix.org)> Nice :D
<re_irc>
< (@korken89:matrix.org)> I wonder how good the "chinese" 80mm thermal printers are
<re_irc>
< (@korken89:matrix.org)> There is an army of them with USB/Ethernet input
<re_irc>
< (@korken89:matrix.org)> I think I'll get one of those as well and lets hope they have copied Epson's interface like everyone else :D
<re_irc>
<henrik_alser> Lol probably!
<re_irc>
<henrik_alser> : One gotcha with the above printer is it prints garbage chars if you supply it with less than 7.5V or so, took me a while to figure out :)
<re_irc>
<henrik_alser> As usual datasheets are to be considered false until proven otherwise
<re_irc>
< (@adamgreig:matrix.org)> hi room, meeting time again! agenda is https://hackmd.io/PZubMN1rT96Ybb-w4eWzHg, please add anything you'd like to discuss and we'll start in about 5min
<re_irc>
< (@adamgreig:matrix.org)> ok, let's go! first up, we'll have our usual two weeks off starting next week, so no meeting until the 10th jan
<re_irc>
< (@adamgreig:matrix.org)> it seems like a while ago now but we renamed alloc-cortex-m to embedded-alloc as it now uses critical-section to do locks, which means it works on any platform with a critical-section impl; it's been released as embedded-alloc 0.5
<re_irc>
< (@adamgreig:matrix.org)> hopefully quite soon it will be possible to use on stable rust, too
<re_irc>
< (@adamgreig:matrix.org)> we're still collecting items for the This Year In Embedded Rust post here, please leave a comment with anything you'd like to mention: https://github.com/rust-embedded/blog/issues/196
<re_irc>
< (@adamgreig:matrix.org)> any other announcements?
<re_irc>
< (@adamgreig:matrix.org)> cool, one other thing i thought worth briefly mentioning is https://github.com/rust-embedded/cortex-m/pull/455 which is a proposed feature for cortex-m-rt that causes it to write all ram with 0 at startup
<re_irc>
< (@adamgreig:matrix.org)> the necessity was driven by a microcontroller where the ram has some sort of checksumming hardware and a partial write to uninitialised memory apparently caused problems
<re_irc>
< (@adamgreig:matrix.org)> it turns out you can do this with a pre_init hook so long as you write that hook in asm (or as a naked fn, but that's not currently allowed in cortex-m-rt aiui?)
<re_irc>
< (@adamgreig:matrix.org)> it's still an easy feature to include in c-m-rt, and somewhat nicer to have it included than require the global_asm call, but maybe it's too niche?
<re_irc>
< (@therealprof:matrix.org)> I think the presented case is sound.
<re_irc>
< (@newam:matrix.org)> I see it a lot on custom ASICs, I don't think it's too niche
<re_irc>
< (@therealprof:matrix.org)> I've seen such hardware myself and it's actually possible that this will at some point turn into an actual requirement for new "security" processors showing up.
<re_irc>
<Ralph> : i posted this a few days ago here in the channel, but i think it was missed: "alloc-cortex-m" on crates.io doesn't state that it has been superseeded by "embedded-alloc", so users of it might not notice that they should switch to the new crate name. i'd suggest releasing a new 0.4.4 which just contains an updated README pointing to the new crate name
<re_irc>
< (@adamgreig:matrix.org)> ah, good idea, thanks
<re_irc>
< (@adamgreig:matrix.org)> : as in, a requirement that the runtime starts by writing 0 to all of ram?
<re_irc>
< (@adamgreig:matrix.org)> i wonder about things like: is 0 always ok or does it sometimes need to be other bytes? for stack painting you might use like 0x55 or whatever
<re_irc>
< (@adamgreig:matrix.org)> and: is just the RAM section from memory.x ok or should it support multiple sections somehow?
<re_irc>
< (@adamgreig:matrix.org)> I fear that those cases will likely always need a custom pre-init, so the question is how common the base case of "just RAM section, just 0s" is
<re_irc>
< (@therealprof:matrix.org)> I think all 0s or all 1s are common values. I don't remember whether the value actually mattered, the overwriting was the important case.
<re_irc>
< (@adamgreig:matrix.org)> makes sense
<re_irc>
< (@adamgreig:matrix.org)> so on balance you'd include the zero-init-ram feature?
<re_irc>
< (@therealprof:matrix.org)> One of the reasons for enforcing that is that glitching is causing more and more troubles for chip makers.
<re_irc>
< (@adamgreig:matrix.org)> yea, though eg the stm32h7 has ecc on (some of) the ram and does it in 8-byte chunks, but doesn't require it all be written at startup to work
<re_irc>
< (@therealprof:matrix.org)> Yeah, but how does ECC prevent leftover content from the previous software run?
<re_irc>
< (@adamgreig:matrix.org)> hmm
<re_irc>
< (@adamgreig:matrix.org)> indeed, I dunno what it does about reading uninit memory which presumably doesn't yet have valid ecc
<re_irc>
< (@adamgreig:matrix.org)> presumably attempts to correct it 🙃
<re_irc>
< (@adamgreig:matrix.org)> in the h7's case you ideally would want to support multiple ram regions, but we have this problem in general really and the solution to that will probably have to be cleverer and more general
<re_irc>
< (@therealprof:matrix.org)> I guess so, but the idea here is. You run the software, make it do secure stuff, glitch it and then exploit the content still leftover in RAM somehow.
<re_irc>
< (@adamgreig:matrix.org)> so maybe for now it suffices to just zero-init the RAM section?
<re_irc>
< (@therealprof:matrix.org)> : Which other sections did you have in mind?
<re_irc>
< (@adamgreig:matrix.org)> well on an h7 you have like axisram, sram1, sram2, sram3, sram4, dtcm, itcm, and backup sram
<re_irc>
< (@adamgreig:matrix.org)> and all of those have their own ecc protection and have different ranges in the address space
<re_irc>
< (@adamgreig:matrix.org)> with cortex-m-rt as it is now, you just tell it about one "RAM" section, and you can otherwise customise memory.x to stick stacks elsewhere and allow you to manually put variables elsewhere, but it won't (zero-)initialise statics in sections besides RAM
<re_irc>
< (@adamgreig:matrix.org)> this is a long-standing issue in c-m-rt though
<re_irc>
< (@therealprof:matrix.org)> Sounds about right to me.
<re_irc>
< (@adamgreig:matrix.org)> so it would be nice to fix, but probably when we figure out how to do that, we can extend zero-init-ram to cover all sections or something like that
<re_irc>
< (@therealprof:matrix.org)> Yeah, start small, can always extend later.
<re_irc>
< (@adamgreig:matrix.org)> OK, i'll do a final review on that PR and let's plan to include it in c-m-rt, then
<re_irc>
< (@adamgreig:matrix.org)> it'l need adding to the documentation and so on
<re_irc>
< (@adamgreig:matrix.org)> next up, yanking c-s 0.2.x?
<re_irc>
< (@adamgreig:matrix.org)> I guess just <=0.2.7
<re_irc>
< (@dirbaio:matrix.org)> yeah, all 0.2.x except 0.2.8
<re_irc>
< (@adamgreig:matrix.org)> I think all the breakage that's gonna happen has happened now due to 0.2.8, anyone on =0.2.7 should update anyway
<re_irc>
< (@dirbaio:matrix.org)> from
<re_irc>
< (@dirbaio:matrix.org)> that there's less benefit to yanking, which is true
<re_irc>
< (@adamgreig:matrix.org)> if they have a =0.2.7 it might be intentional but it's still wrong, is our point of view, right?
<re_irc>
< (@dirbaio:matrix.org)> but there's less downside to yanking as well, as most of the breakage is done
<re_irc>
< (@dirbaio:matrix.org)> doing "=0.2.7" could be "correct" if the default "disable irqs" impl is correct for your target
<re_irc>
< (@dirbaio:matrix.org)> but still, changing to "1.0" is extremely easy
<re_irc>
< (@dirbaio:matrix.org)> so I still think we should yank
<re_irc>
< (@adamgreig:matrix.org)> yea
<re_irc>
< (@adamgreig:matrix.org)> I reckon go for it now and if it turns out to really cause problems for someone over christmas we always have the option to unyank
<re_irc>
< (@dirbaio:matrix.org)> ah right yanking is not permanent
<re_irc>
< (@dirbaio:matrix.org)> still, I can't think of any "problem" that can't be solved by upgrading to 1.0
<re_irc>
< (@dirbaio:matrix.org)> also 0.2.x hasn't seen much use other than through "atomic-polyfill 0.1", and that also got a release bumping it to "critical-section 1.0" :D
<re_irc>
< (@adamgreig:matrix.org)> yea
<re_irc>
< (@thejpster:matrix.org)> There was quite a bit of breakage that I saw. We wrote a blog about it.
<re_irc>
< (@adamgreig:matrix.org)> the whole point of 0.2.8 was that 0.2.7 is unsound so it seems half-complete to have 0.2.8 and not yank 0.2.7
<re_irc>
< (@adamgreig:matrix.org)> are you ok to do the yanking?
<re_irc>
< (@adamgreig:matrix.org)> : yea, 0.2.8 caused a lot of breakage, but yanking 0.2.7 now seems like it shouldn't cause more
<re_irc>
< (@adamgreig:matrix.org)> it would be nice if cargo had some sort of feature where you could print a message to people when it updates crates to a newer version or something
<re_irc>
< (@adamgreig:matrix.org)> I think the 0.2.8 breakage was primarily defmt-rtt 0.3? which is of course widely used but the new version was already released at that point
<re_irc>
< (@thejpster:matrix.org)> I guess it’ll keep happening though as people do their first build since the change, eg push to a new branch and run CI.
<re_irc>
< (@thejpster:matrix.org)> It was unsound but not on all chips?
<re_irc>
< (@adamgreig:matrix.org)> right, it _could_ be unsound on chips where disabling all interrupts isn't a valid critical section
<re_irc>
<thejpster> But let’s not go over it again. I’d just yank 0.2.7
<re_irc>
< (@adamgreig:matrix.org)> or rather it would be unsound on those chips, and not on chips where that's not he case
<re_irc>
< (@adamgreig:matrix.org)> * the
<re_irc>
<thejpster> If you’re pinned you can still pull a yanked version
<re_irc>
< (@adamgreig:matrix.org)> yea
<re_irc>
< (@adamgreig:matrix.org)> so yanking should have fairly minimal impact (if you're pinned it makes no difference, if you update you'll get 0.2.8 normally)
<re_irc>
< (@adamgreig:matrix.org)> just signals "0.2.7 is deliberately removed and sorry for the break in 0.2.8"
<re_irc>
< (@dirbaio:matrix.org)> the intent behind 0.2.8 was:
<re_irc>
- All 0.2.x was unsound. It wasn't possible to remove the unsoundness without breaking changes.
<re_irc>
- Therefore releasing a 0.2.8 that removes unsoundness and breaks only some users is better
<re_irc>
- Yanking all 0.2.x would have broken ALL users
<re_irc>
<Ralph> basically what's already written in the issue / my last comment: i've used "PwmPin" from e-h 0.x in my motor driver (https://github.com/rursprung/tb6612fng-rs) and then afterwards realised that it's gone in 1.0.0. from what i gathered in the ticket most of the other traits were removed because they actually needed to know actual time information and there's no standardisation for that yet, but the "PwmPin" just needs a...
<re_irc>
... duty - which isn't a time information. there was a pre-existing suggestion in the ticket to re-ad it to 1.0 with a generic "Duty" (instead of an associated type). i'd like to get that discussion started again to hopefully land this in 1.0 :)
<re_irc>
< (@dirbaio:matrix.org)> the issue with unconstrained associated types is you can't write code that works with all HALs
<re_irc>
< (@dirbaio:matrix.org)> because one HAL might choose "Duty=u32" and another might choose "Duty=f32"
<re_irc>
< (@dirbaio:matrix.org)> and even worse:
<re_irc>
> The implementer is free to choose a float / percentage representation (e.g. 0.0 .. 1.0) or an integer representation (e.g. 0 .. 65535)
<re_irc>
< (@dirbaio:matrix.org)> so one HAL might choose u32 in "0..100", another an u32 in "0..32768"
<re_irc>
< (@dirbaio:matrix.org)> you can't for example write a "fn set_duty_to_50_percent(pin: &mut impl PwmPin)"
<re_irc>
<thejpster> I can’t help but think a u32 should be good enough for everyone?
<re_irc>
so it won't work on HALs using f32 or u32 for example
<re_irc>
<thejpster> It’s not overly expensive to pass around, and you can shift it if you want 16 or 12 or 8 bits. If you want 0..100 you have to do some maths.
<re_irc>
<Ralph> how about standardising a "PercentagePwmPin"(stupid name, sorry) which takes an u8 going from 0..100? yes, for some that might not be accurate enough, but i guess for most use-cases that'd already be "good enough" and would be better than not having anything in e-h 1.0?
<re_irc>
< (@dirbaio:matrix.org)> yeah, the solution is "embedded-hal" picking one particular type and representation
<re_irc>
<Ralph> : yeah, i took a shortcut because my device (STM32F401RE) uses u16. that's the main reason the crate isn't released yet 🤷
<re_irc>
< (@adamgreig:matrix.org)> it's worth bearing in mind we can always add things to e-h 1.0 in a later release without breaking things, we specifically removed a lot of things from the 1.0 target to try and get it done
<re_irc>
< (@adamgreig:matrix.org)> i.e. there's no deadline, just it would be nice to have once we feel we can make a good decision
<re_irc>
< (@adamgreig:matrix.org)> if you were going to have a PercentagePwmPin with a u8 it seems like 0-255 would be a better range choice?
<re_irc>
< (@adamgreig:matrix.org)> though for many timer setups you end up with a duty cycle range that's 0 up to the timer period, right? which might be any number
<re_irc>
< (@adamgreig:matrix.org)> so even if e-h standardised on a u32 0 to 0xFFFF_FFFF and said hals can just "shift it down" to get whatever number of bits full-scale they want, you may well end up having to do a linear scaling to get the right range, which might be expensive
<re_irc>
< (@adamgreig:matrix.org)> or ensure the timers are only set up with powers-of-two periods I guess
<re_irc>
< (@dirbaio:matrix.org)> currently the 0.2 trait has "get_max_duty() -> Duty"
<re_irc>
< (@dirbaio:matrix.org)> so the user of the trait has to do such linear scaling
<re_irc>
<Ralph> : yep, with the "percentage" suggestion you'd have to do linear scaling (based on the max. duty)
<re_irc>
< (@dirbaio:matrix.org)> if the range is fixed, it's the HAL that would do the scaling
<re_irc>
<Ralph> : exactly, that'd just move the scaling problem from the user to the HAL
<re_irc>
<thejpster> As a user of the pin, I’m probably making a buzzing sound or moving a servo. Nothing with critical accuracy.
<re_irc>
< (@dirbaio:matrix.org)> and if the HAL cares about efficiency, it could set the period to a power of 2, so that the scaling is just a shift
<re_irc>
< (@adamgreig:matrix.org)> some people are making buzzing sounds but there's lots of uses for pwm pins that do want every bit of resolution
<re_irc>
< (@adamgreig:matrix.org)> if i'm doing a dc-dc converter my feedback loop definitely cares that it gets all the duty cycle control it can get
<re_irc>
<thejpster> : Or use the hardware multiplier it knows it has.
<re_irc>
<Ralph> : but in that case you can never be hardware-agnostic as you have to know the max. duty of the specific hardware to get the most out of it?
<re_irc>
<thejpster> Because the HAL is chip specific and knows these things.
<re_irc>
< (@adamgreig:matrix.org)> hmm, that's true, for actual end user firmware you can always just be using the hal's own methods instead of the e-h traits
<re_irc>
< (@adamgreig:matrix.org)> so maybe the majority of generic drivers could be ok with something like 0-100 (though it still feels like 0-255 would be nicer :P)
<re_irc>
< (@newam:matrix.org)> : For a lot of ASICs at my old job it was any value, just to initialize the SECDED.
<re_irc>
Multiple sections usually doesn't come up in my experience, but if it does usually it requires a heavily tailored solution that wouldn't be covered by c-m-rt anyway
<re_irc>
<thejpster> Arduino analogWrite just takes a u8.
<re_irc>
< (@newam:matrix.org)> Whoops, sorry, that's off topic now, I'm out of town and the internet is spotty
<re_irc>
< (@adamgreig:matrix.org)> yea, if we're going to fix a range where some number is always full scale then maybe 0-255 is nicer than 0-100 and should be basically as useful for generic drivers
<re_irc>
< (@adamgreig:matrix.org)> except for maybe some questions about whether 255 is 100% duty cycle or 255/256 duty cycle, and what 50% looks like
<re_irc>
< (@therealprof:matrix.org)> Why not go u16::MAX or u32::MAX?
<re_irc>
< (@burrbull:matrix.org)> any fixed range will be bad idea
<re_irc>
< (@burrbull:matrix.org)> as always present rounding issue
<re_irc>
< (@adamgreig:matrix.org)> yea, but just for one generic interface for generic drivers to use?
<re_irc>
< (@adamgreig:matrix.org)> the HAL itself can and should still provide a more explicit API that lets users put exact u16 that don't get scaled (or whatever is appropriate), but the HAL could also offer a 0-255 interface that it scales internally (at the cost of rounding errors and computation time) to allow it to be the same as anything else
<re_irc>
< (@adamgreig:matrix.org)> : indeed, could pick those instead, takes more memory and gives more resolution
<re_irc>
< (@therealprof:matrix.org)> Scaling down should be rather easy, the other way around not so much.
<re_irc>
<thejpster> And you can add a 16 bit API later with a default impl.
<re_irc>
< (@therealprof:matrix.org)> I know a lot of people which are rather unhappy with the analogWrite() from good old AVR times.
<re_irc>
<thejpster> 16 bits is what, 96 dB?
<re_irc>
< (@adamgreig:matrix.org)> enough dB for anyone 😆 though i bet most timers do not get set up in a way that permits 16 bits of duty cycle resolution
<re_irc>
< (@dirbaio:matrix.org)> I imagine 32bit will be annoying for msp430, avr?
<re_irc>
<thejpster> If you want 24 bit output accuracy you probably can’t run on any random chip for other reasons.
<re_irc>
< (@dirbaio:matrix.org)> u16 sounds good to me
<re_irc>
< (@adamgreig:matrix.org)> yea, i feel like the majority of timers out there are 16 bit counters, even if you don't get all that worth of useful range most of the time in pwm mode
<re_irc>
< (@adamgreig:matrix.org)> even the trusty atmega128 has two 16 bit timers :p
<re_irc>
< (@dirbaio:matrix.org)> re the "255/256" issue, how does PWM hardware work eactly?
<re_irc>
an N bits counter, and make output high if "counter < duty"?
<re_irc>
< (@adamgreig:matrix.org)> do we define u16::MAX to be 100% duty cycle or 65535/65536? an annoying fencepost thing but sometimes you do want 100% to be an option
<re_irc>
< (@dirbaio:matrix.org)> it can't be "counter <= duty" because "duty=0" would go high when "counter=0"
<re_irc>
< (@dirbaio:matrix.org)> but that means (assuming a 16bit counter) that "duty=65535" is actually "65535/65536" duty, not 100% duty
<re_irc>
< (@dirbaio:matrix.org)> to get 100% duty you'd need "duty=65536", but that no longer fits in a u16 🤔
<re_irc>
< (@adamgreig:matrix.org)> yea, that's the issue
<re_irc>
< (@adamgreig:matrix.org)> 0-100 resolves this by having 101 values
<re_irc>
<thejpster> I think 65535 is fully on and 0 is usually but not always fully off
<re_irc>
< (@adamgreig:matrix.org)> often when configuring a timer you have the reload value not be a full u16, so you can set the pwm to one greater to get 100%
<re_irc>
<thejpster> Reading the Arduino docs (where it’s 255 and zero).
<re_irc>
< (@adamgreig:matrix.org)> "usually but not always" sounds a bit cursed
<re_irc>
< (@dirbaio:matrix.org)> perhaps do "0-32768", for a 15bit counter?
<re_irc>
< (@dirbaio:matrix.org)> +so it's still a nice power of 2
<re_irc>
< (@adamgreig:matrix.org)> that could work
<re_irc>
< (@adamgreig:matrix.org)> or you can call 65535 100% and the hal has to scale things as appropriate
<re_irc>
< (@dirbaio:matrix.org)> no, 32768 would be 100%
<re_irc>
< (@adamgreig:matrix.org)> no, I mean, e-h could say that 0 is 0% and 65535 is 100%, the steps are no longer 1/65536 big but that's "ok", and the hal has to figure it out
<re_irc>
< (@therealprof:matrix.org)> Specialcasing "always on" kind of makes sense anyway.
<re_irc>
< (@adamgreig:matrix.org)> the hal most likely already has to scale 0-65535 to map to 0-max_duty, so it scales to max_duty+1 or whatever instead and it will get 100% at 65535
<re_irc>
< (@dirbaio:matrix.org)> that'd require dividing by 65535 which is not a power of 2 though
<re_irc>
< (@adamgreig:matrix.org)> well you're probably not going to divide a u16 by 65536 either right?
<re_irc>
< (@adamgreig:matrix.org)> 0-100 sure starts to look appealing lol
<re_irc>
< (@dirbaio:matrix.org)> I guess this needs a survey of what the hardware out there actually works
<re_irc>
< (@dirbaio:matrix.org)> but
<re_irc>
<thejpster> Is there an API for Centre Aligned vs Edge Aligned?
<re_irc>
< (@dirbaio:matrix.org)> I guess there's either:
<re_irc>
- 0 is always low, 65535 is almost-always high
<re_irc>
- 0 is almost-always low, 65535 is always high
<re_irc>
< (@dirbaio:matrix.org)> but there's no hardware where
<re_irc>
0 is always low, 65535 is always high
<re_irc>
<thejpster> Because I think 65535 vs 65536 is moot unless you can set that. And the frequency.
<re_irc>
< (@adamgreig:matrix.org)> the frequency will be set by using the HAL to create this pwmpin trait, and that could also permit setting centre vs edge aligned if need be
<re_irc>
< (@adamgreig:matrix.org)> so yea, the hal should provide such APIs, but it's outside the scope of the e-h pwmpin trait
<re_irc>
< (@eldruin:matrix.org)> we can also have set_duty with 1/65536 steps and a separate set_full_on /off method. That is how the PCA9685 works. In that chip is annoying that the full modes can take precedence over the duty and so on, but that for pwmPin we can say set_duty deactivates set_full_on for example
<re_irc>
< (@adamgreig:matrix.org)> : but usually in hardware it will actually be like 0 is always low, 19999 is almost-always high, 20000 is always high
<re_irc>
<thejpster> Ok, so the driver must be given a configured pin and cannot enforce these properties?
<re_irc>
< (@therealprof:matrix.org)> I don't think that the error caused by that offset is high enough to actually matter.
<re_irc>
< (@adamgreig:matrix.org)> it's not in a 16 bit timer, but if the HAL is scaling it to 8 bit then it's suddenly quite significant
<re_irc>
< (@adamgreig:matrix.org)> it's not in a 16-bit timer where there are 16 bits of useful range for the PWM duty, I mean, which is almost never
<re_irc>
< (@dirbaio:matrix.org)> : because the period will be some number like 20000, and not the full 16bit?
<re_irc>
< (@adamgreig:matrix.org)> yea
<re_irc>
< (@adamgreig:matrix.org)> because the user has set some frequency and that frequency is probably not exactly what gives 65535 period from the timer clock
<re_irc>
< (@dirbaio:matrix.org)> if we spec the trait as "0 = always low, 65536 = always high", then the HAL has to do "duty * period / 65536" which is cheap
<re_irc>
< (@dirbaio:matrix.org)> if we spec the trait as "0 = always low, 65535 = always high", then the HAL has to do "duty * period / 65535" which is less cheap because the division is no longer a shift
<re_irc>
< (@therealprof:matrix.org)> : Huh?
<re_irc>
<thejpster> 255/256 is 99.6%
<re_irc>
< (@adamgreig:matrix.org)> : if the e-h trait uses u16 and says 65535 is 65535/65536 duty, but the hal is implemented for an 8-bit timer or a timer where there are only 8 bits worth of duty cycle range, the difference in being "fully on" or "one count less than fully on" become significant
<re_irc>
<thejpster> we can have on, off, and variable(u16) methods?
<re_irc>
we can also have set_duty with 1/65536 steps and a separate set_full_on /off method. That is how the PCA9685 works. In that chip is annoying that the full modes can take precedence over the duty and so on, but that for pwmPin we can say set_duty deactivates set_full_on for example
<re_irc>
< (@adamgreig:matrix.org)> : in practice can it do this? even if those variables are promoted to u32 i feel like that's probably going to lose a lot of accuracy? haven't thought about it precisely
<re_irc>
< (@therealprof:matrix.org)> : If the driver scales the u16 to an u8, I don't see why 65535/65536 matters.
<re_irc>
< (@adamgreig:matrix.org)> because 65535/65536 will scale to 255/256, which is a much bigger relative error
<re_irc>
< (@adamgreig:matrix.org)> (because it's scaled by shifting down eight bits, presumably)
<re_irc>
<thejpster> Where variable(0) is off or nearly off and variable(65535) is on or nearly on and we are deliberately hazy because hardware varies in practice.
<re_irc>
< (@adamgreig:matrix.org)> hmm
<re_irc>
< (@adamgreig:matrix.org)> i don't especially like the nonlinearity but for many applications having the separate methods might be ok?
<re_irc>
< (@therealprof:matrix.org)> : But it wouldn't because always on is special cased.
<re_irc>
< (@dirbaio:matrix.org)> separate methods is annoying, it forces you to turn maths into "if"s
<re_irc>
< (@adamgreig:matrix.org)> yea, I feel like a lot of drivers would end up with like "if demand == 0 { set_zero() } elif demand == 255 { set_full() } else { set_variable(demand) }" or whatever
<re_irc>
< (@adamgreig:matrix.org)> which the HAL could just as well do
<re_irc>
< (@dirbaio:matrix.org)> exactly
<re_irc>
< (@adamgreig:matrix.org)> heck, I guess you could just say that 0 is 0%, 65534 is 65534/65536, and 65535 is 100%
<re_irc>
< (@adamgreig:matrix.org)> maybe that appeases everyone
<re_irc>
< (@therealprof:matrix.org)> : Exactly.
<re_irc>
< (@dirbaio:matrix.org)> lol
<re_irc>
< (@therealprof:matrix.org)> And then it doesn't matter if it's an 8bit, 12bit or 16bit timer.
<re_irc>
< (@adamgreig:matrix.org)> you get precise 0 and 100% duty cycle settings, you get easy computation of the duty to program from the demanded duty because the step size is a power of 2, and you special case 100%
<re_irc>
< (@adamgreig:matrix.org)> the downside is you introduce a weird nonlinearity right around the 100% mark
<re_irc>
< (@adamgreig:matrix.org)> but probably no worse than you are introducing anyway by scaling the full u16 range to whatever the actual duty cycle range for the timer is, tbh
<re_irc>
<thejpster> Which is a 0.0015% error
<re_irc>
< (@eldruin:matrix.org)> sounds like a winner to me
<re_irc>
<thejpster> Wish we had Ada ranged types
<re_irc>
< (@adamgreig:matrix.org)> it's a 0.0015% error if your timer is somehow able to do 16 bits of duty cycle range, but in reality it's probably more like a 0.4% error (if the timer has 8 bits of range)
<re_irc>
<thejpster> enum Duty { Off, Variable(1..=65534), On }
<re_irc>
< (@adamgreig:matrix.org)> or like, it might not be uncommon for the range to just be 100 counts, so your error is a full 1%
<re_irc>
< (@adamgreig:matrix.org)> but perhaps that's a reasonable price to pay here
<re_irc>
< (@therealprof:matrix.org)> Percent means annoying maths.
<re_irc>
< (@adamgreig:matrix.org)> (for example: your stm32 timer runs at 48MHz clock, you want a 10kHz PWM output, the period is 4800, so the duty cycle is 0-4801 for 0-100%, and one step is a 0.02% error)
<re_irc>
< (@adamgreig:matrix.org)> so the 0-65535 you feed into the e-h trait is scaled to 0-4800 by the HAL, and the 65535 value is special-cased to 4801
<re_irc>
<thejpster> So 65535 is 4801, 0 is 0, and we do maths in the middle
<re_irc>
<thejpster> Snap
<re_irc>
< (@adamgreig:matrix.org)> not quite: 65535 is 4800, but if you actually get 65535 you write 4801 instead
<re_irc>
<thejpster> Yeah that’s what I meant
<re_irc>
< (@adamgreig:matrix.org)> if you scaled so that 65535 is 4801, then you're actually saying the input is steps of 1/65535 instead of 1/65536
<re_irc>
< (@therealprof:matrix.org)> Or don't use the timer at all because it's cheaper to just do always on. 😉
<re_irc>
< (@adamgreig:matrix.org)> right, maybe on some hardware it is, HAL's choice
<re_irc>
< (@adamgreig:matrix.org)> or on some hardware you _can't_ do 100% duty cycle by setting a period, so you _have_ to set always-on instead
<re_irc>
< (@adamgreig:matrix.org)> but the PwmPin trait just takes a u16 where 0 is 0%, 65535 is 100%, and each count is 1/65536 worth of duty
<re_irc>
< (@adamgreig:matrix.org)> we've gone way over time for this meeting 😅
<re_irc>
< (@eldruin:matrix.org)> If we reach an agreement, it would be worth it
<re_irc>
< (@adamgreig:matrix.org)> does anyone have any concerns with this one?
<re_irc>
<Ralph> : sorry for bringing up this controversial topic and then not even contributing 😅 (but i'm no expert in this, so i'm happy to have started the conversation of the experts 🙂)
<re_irc>
< (@therealprof:matrix.org)> : I suggested that, so no. 😉
<re_irc>
<thejpster> I think it’s fine. 8 more bits than arduino.
<re_irc>
<thejpster> And the possible errors seem small.
<re_irc>
< (@therealprof:matrix.org)> And it's convenient to work with.
<re_irc>
< (@adamgreig:matrix.org)> yea. it just means that 65535/65536 duty is not expressible, and there's a non-linear 2x step going from 65534 to 65535, but... I think in practice that's unlikely to be too much of a restriction
<re_irc>
< (@adamgreig:matrix.org)> your control loop or whatever is probably going to get sad around the 100% duty anyway, and in almost all real applications I expect there will be similar or worse non-linearities between most of those u16 counts due to the hal scaling
<re_irc>
<thejpster> A bit of PCB capacitance and I’m not sure you’d notice
<re_irc>
< (@adamgreig:matrix.org)> hmmm, I think it would be very easily measured, the capacitance will slow the edges but not change the timing between them
<re_irc>
< (@adamgreig:matrix.org)> but anyway unlikely to be a problem
<re_irc>
< (@adamgreig:matrix.org)> it just needs to be very explicit that this scaling is in use, because it's not very obvious and hals might end up trying to just scale 0-65535 as 0-100% which isn't quite right
<re_irc>
< (@adamgreig:matrix.org)> though... probably no one would notice that error anyway....
<re_irc>
< (@adamgreig:matrix.org)> cool, ok
<re_irc>
< (@adamgreig:matrix.org)> shall I write a comment about this on that issue and then we can wrap up the meeting 😅
<re_irc>
< (@adamgreig:matrix.org)> haha no wonder you were quiet for a few minutes there
<re_irc>
< (@adamgreig:matrix.org)> I guess I don't need to write a comment :P
<re_irc>
< (@adamgreig:matrix.org)> not sure about your 1000% duty though :P
<re_irc>
< (@dirbaio:matrix.org)> it just means the pin is REALLY high
<re_irc>
< (@eldruin:matrix.org)> 1000% duty FTW
<re_irc>
< (@dirbaio:matrix.org)> 🙈
<re_irc>
< (@eldruin:matrix.org)> 🤣
<re_irc>
< (@adamgreig:matrix.org)> I think you need to be much more explicit about the weird scaling we're using: the input 0-65535 maps to 0/65536 to 65535/65536 duty cycle, and as a special case, 65535 maps to 65536/65536 (100%) duty
<re_irc>
< (@dirbaio:matrix.org)> I'm not sure if we should spec that
<re_irc>
< (@adamgreig:matrix.org)> you could write it as 0-65534 maps to 0/65536 - 65534/65536, and 65535 to 65536/65536, it's a bit clearer
<re_irc>
< (@dirbaio:matrix.org)> the HAL could do "really linear" scaling with "real_duty = duty * period / 65535"
<re_irc>
< (@dirbaio:matrix.org)> (promoting to u32 as needed)
<re_irc>
< (@adamgreig:matrix.org)> yea, I guess we can allow that if the hal wants to?
<re_irc>
< (@adamgreig:matrix.org)> meh, it is less well specific and introduces different errors but doesn't have a nonlinearity so it's nicer if the hal can do it easily
<re_irc>
< (@dirbaio:matrix.org)> I think it's already implicit that the HAL can opt in to do hax to make the math faster at the cost of some error
<re_irc>
<thejpster> Why is it 90% error boilerplate ?
<re_irc>
< (@dirbaio:matrix.org)> thejpster: that's how errors in EH1.0 work
<re_irc>
<thejpster> And the ErrorKind seems not very helpful
<re_irc>
< (@adamgreig:matrix.org)> cool, thanks for putting together the PR then
<re_irc>
<thejpster> Right but did they need to be redeclared in every module?
<re_irc>
< (@dirbaio:matrix.org)> thejpster: ErrorKind has to be different for each module
<re_irc>
< (@dirbaio:matrix.org)> thejpster: agreed. It's "non_exhaustive" so that new kinds can be added backward-compatibly
<re_irc>
< (@eldruin:matrix.org)> it would make more sense if we had sensible error variants for PWM
<re_irc>
< (@dirbaio:matrix.org)> I didn't add any because I dont' know what error variants to add
<re_irc>
< (@eldruin:matrix.org)> yeah, maybe somebody else has an idea?
<re_irc>
< (@dirbaio:matrix.org)> SetDuty should be mostly infallible, except for i2c/spi errors if you're using an external pwm chip
<re_irc>
< (@eldruin:matrix.org)> yeah, other than that, we are using the full range of the value and the hal should just do whatever necessary so no "InvalidValue" variant
<re_irc>
<thejpster> There are no API logic errors.
<re_irc>
< (@dirbaio:matrix.org)> the ErrorKind idea is more useful with serial, i2c
<re_irc>
<thejpster> No “you gave me 500 and I said no more than 496”
<re_irc>
< (@dirbaio:matrix.org)> a driver could treat "i2c NACK" differently than "i2c hardware is FUBAR"
<re_irc>
< (@eldruin:matrix.org)> I think a single other variant does not make much sense if it is clear no other variants are possible because you can already do that without an "ErrorKind". the driver can do nothing about it regardless
<re_irc>
<thejpster> Hmmm. So “Transient” and “Fatal”?
<re_irc>
< (@adamgreig:matrix.org)> there's still an error even with no errorkind, right? which can wrap an underlying transport error
<re_irc>
< (@dirbaio:matrix.org)> "ErrorKind" is "non_exhaustive", so we CAN add more variants in the future backwards-compatibly
<re_irc>
<thejpster> If so errorkind should be shared across traits in the HAL?
<re_irc>
< (@dirbaio:matrix.org)> if we DON'T have "ErrorKind" at all, we CAN'T add it later
<re_irc>
< (@adamgreig:matrix.org)> for i2c it's just that he specific i2c operation might have different types of generic errors that drivers might care to know about
<re_irc>
< (@adamgreig:matrix.org)> * the
<re_irc>
< (@dirbaio:matrix.org)> this was my reasoning for adding a dumb ErrorKind
<re_irc>
<thejpster> I2C can have bus collisions right? Which it’s safe to retry?
<re_irc>
< (@dirbaio:matrix.org)> and because I thought all traits had it
<re_irc>
< (@adamgreig:matrix.org)> like, NAK is appropriate for i2c errorkind, but doesn't make sense for spi errorkind
<re_irc>
<thejpster> Or should it retry internally, making all returned errors fatal?
<re_irc>
< (@eldruin:matrix.org)> yeah, we can do it for future-proofness. It does not change anything I guess. just a bit more boilerplate code inside e-h. in the hal that should be 1 line
<re_irc>
< (@eldruin:matrix.org)> * hals
<re_irc>
< (@dirbaio:matrix.org)> if we do it, should we add one to GPIO as well?
<re_irc>
< (@dirbaio:matrix.org)> and to Delay? 😂
<re_irc>
< (@eldruin:matrix.org)> yes, indeed
<re_irc>
<thejpster> They should match, yes.
<re_irc>
<thejpster> How can delay fail?
<re_irc>
< (@dirbaio:matrix.org)> oh boi the fallible delay discussion :D
<re_irc>
<thejpster> Oh no
mightypork has joined #rust-embedded
<re_irc>
<thejpster> Ok, let’s not
<re_irc>
< (@dirbaio:matrix.org)> iirc reasons were "consistency" and "you might use an off-chip timer through i2c/spi"
<re_irc>
< (@dirbaio:matrix.org)> I honestly think we could make an exception for just THAT one trait and make it infallible
<re_irc>
< (@dirbaio:matrix.org)> but I'm OK with either
<re_irc>
<thejpster> I mean drivers are just going to ?
<re_irc>
< (@dirbaio:matrix.org)> or to ".unwrap()" :D
<re_irc>
<thejpster> 😭
<re_irc>
< (@adamgreig:matrix.org)> I wandered off a little while ago but anyway that's it for meetings this year, thanks everyone and see you in 2023!
<re_irc>
< (@dirbaio:matrix.org)> TAIT is in FCP 🚀
<re_irc>
< (@dirbaio:matrix.org)> just right after we switched to AFIT 🤪
<re_irc>
< (@dirbaio:matrix.org)> this means no async traits in stable for a bit longer
<re_irc>
< (@dirbaio:matrix.org)> AFIT is much better anyway
<re_irc>
< (@dirbaio:matrix.org)> one interesting application of TAIT is it allows to make a "singleton!()" macro that doesn't require specifying the type :D
<re_irc>
< (@dirbaio:matrix.org)> one interesting application of TAIT is it allows writing a "singleton!()" macro that doesn't require specifying the type :D
<re_irc>
< (@grantm11235:matrix.org)> It consists of a "get_max_duty" method and a "set_duty" method, as well as some convenience methods
<re_irc>
< (@grantm11235:matrix.org)> This means that the HAL doesn't do any math, all the math is done by the user or by the convenience methods
<re_irc>
< (@grantm11235:matrix.org)> So the user only pays for the math that they actually use
<re_irc>
< (@dirbaio:matrix.org)> why is it better to do the math at the user side?
<re_irc>
< (@grantm11235:matrix.org)> Because the user is probably already doing their own math too. It is better for performance and accuracy to be able to combine that math into one step
<re_irc>
< (@grantm11235:matrix.org)> Instead of doing user math, then doing hal math afterwards
crabbedhaloablut has quit [Ping timeout: 255 seconds]
crabbedhaloablut has joined #rust-embedded
<re_irc>
< (@dirbaio:matrix.org)> hmmm
<re_irc>
< (@dirbaio:matrix.org)> the user could easily write their math to work on 0..65535 though
<re_irc>
< (@dirbaio:matrix.org)> but yea with the helper methods the "it's easier to use" argument goes away 🤔
<re_irc>
< (@grantm11235:matrix.org)> If you want to set a percent, the user would need to convert their number from 0..=100 to 0..=65535, then the hal would need to convert that to 0..=PWM_MAX
<re_irc>
< (@grantm11235:matrix.org)> Vs just calling pwm.set_percent(42), which calls set_fraction(42, 100), which does a total of one multiplication and one division
<re_irc>
< (@grantm11235:matrix.org)> I am assuming that 0 means always off and get_max_duty means always on. So a 16 bit timer would report a max duty of u16::MAX + 1
<re_irc>
< (@grantm11235:matrix.org)> There would also need to be some note about what happens if you try to set the duty above the max value. I think that panicking or returning an error should both be allowed. Maybe the hal should be allowed to silently set the duty cycle to something wrong. Obviously UB is not allowed