-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add reference counting to GPIO pins to init/deinit clock control to port #139
base: main
Are you sure you want to change the base?
Add reference counting to GPIO pins to init/deinit clock control to port #139
Conversation
ebbf70c
to
f0c462d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some kicking-off questions
b0a661e
to
49ccb21
Compare
20fa507
to
9f8c6a4
Compare
9f8c6a4
to
1d57614
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think as an overall comment, since you're refcounting the clocks for GPIO, why isn't this done as part of the clock driver? We already have a good trait, IIRC, for modelling syscon peripherals. Could that be used together with refcounting to have globally refcounted clocks?
src/gpio.rs
Outdated
disable::<peripherals::HSGPIO0>(); | ||
disable::<peripherals::HSGPIO1>(); | ||
disable::<peripherals::HSGPIO2>(); | ||
disable::<peripherals::HSGPIO3>(); | ||
disable::<peripherals::HSGPIO4>(); | ||
disable::<peripherals::HSGPIO5>(); | ||
disable::<peripherals::HSGPIO6>(); | ||
disable::<peripherals::HSGPIO7>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you disable the peripheral during initialization?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did some testing and it looks like the gpio clocks are being enabled somewhere in our embassy_imxrt::init()
function, so enable_and_resetting()
here technically does nothing. I double checked this with asserting cc1.pscctl1().read().hsgpio0_clk().is_disable_clock()
before instantiating the first pin. Since we want to save power, i think these should be off by default. But to your general comment, if we move this to the clock code then this will probably disappear as we can (maybe) disable the clock there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: see comment below for justification for why i don't think moving to the clock driver is correct here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
clocks are enabled as part of gpio::init()
which is called by the application (should it be, though?). Either way, disabling the clocks here is the wrong thing to do. Rather, you should review the current clock usage for this driver and make sure it matches what you're trying to achieve, fixing any discrepancies along the way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should just remove the gpio::init() from embassy_imxrt::init() if now it is automatically enabled and disabled with your changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can the interrupt logic in the artifacts of init()
be moved into the refcounting logic? aka, calling unpend()
and enable()
when initing and pend()
and disable()
when deiniting?
63ea072
to
5062c65
Compare
To @felipebalbi's point as to why this isn't done as part of the clock driver, i think that implementing this on the peripheral level allows for more flexibility since we are using the |
once could argue that a PR implementing refcounting always maintains it balanced, regardless of the method used for balacing those calls. Rust just happens to provide this nice |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need a rebase on main as there is conflicts.
src/gpio.rs
Outdated
disable::<peripherals::HSGPIO0>(); | ||
disable::<peripherals::HSGPIO1>(); | ||
disable::<peripherals::HSGPIO2>(); | ||
disable::<peripherals::HSGPIO3>(); | ||
disable::<peripherals::HSGPIO4>(); | ||
disable::<peripherals::HSGPIO5>(); | ||
disable::<peripherals::HSGPIO6>(); | ||
disable::<peripherals::HSGPIO7>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we should just remove the gpio::init() from embassy_imxrt::init() if now it is automatically enabled and disabled with your changes.
215fb9b
to
c0642ca
Compare
Can the interrupt logic in the artifacts of init() be moved into the refcounting logic? aka, calling |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Please coordinate with @madeleyneVaca to have them test their ADO SoC repos against this change before uptake this. This introduces the drop semantic for gpio so if they are not holding onto the ownership of the pins. It could produce bugs.
c0642ca
to
0fa0e82
Compare
Resolves #61
GPIO port clocks are now disabled if no pin from that port is active.
gpio::init()
has been changed to disable all clocks and only explicitly enable the port clock when a gpio pin (Input, Output, Flex) is instantiated.