-
Notifications
You must be signed in to change notification settings - Fork 2k
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
drivers: support for NXP PCA9685 I2C 16-channel, 12-bit PWM controller #10556
Conversation
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions. |
Can this be merged in a way it becomes partially functional and continue with the fancy stuff as soon as the PR this is depending on are ready? |
From my point of view the driver is ready and could be used. The initial plan was to merge the PWM extension API in PR #10533 first. If you take a look to the test application you can see that PWM extender channels could be used exactly like MCU pwm channels when the module That is, you could checkout the PR and you could use it. I will rebase it later today to the current master. I could also remove the extender parts for the moment, if it helps to merge it. It would be great, if you would test it. |
7613734
to
d73ab2c
Compare
@benpicco Thanks for reviewing. I'm really impressed, so fast and so deep in detail. |
Overall I think this is good, just some minor nits. There are more efficient ways to set those config bits, but since it only happens on init I don't think it's a problem. Sorry for the spotty updates, I should use the review feature next time to add them all at one. @mrusme can you give it a whirl and see if it works for you? |
55e56aa
to
998c862
Compare
I'd squash When the PWM extension code gets finalised you couldn't simply revert 998c862 but would make a new commit anyway. |
I will try, but I'm not sure whether it works. |
No, it leads to conflicts. I would like to leave it as is. |
I could squash |
998c862
to
503373d
Compare
Ok, I solved the conflicts by splitting commit |
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.
The code looks good now.
I'd still like @mrusme to give it a try, but if he doesn't respond we can merge it without him 😉
Another rebase is needed though.
503373d
to
c6bbaac
Compare
Hey there, thanks for the patience and sorry for the delay! I've tested this and all looks good from a general perspective. However, I've experienced a slight issue here which is probably only relevant for me - it does however make this driver unusable to me. Let me explain: For every PWM action a write is being performed. Write then acquires I2C, sets writes the data to the registers and releases the I2C again. That's basically how most drivers run and it's totally fine. In my case, I need to set multiple channels at once, with either identical or different computed values. Hence the poor-man's-driver I wrote for the PCA contains a small hack which allows me to specify whether I2C should be kept acquired. If I was to release the I2C channel between setting PWM for the multiple channels I could end up with a different thread/device acquiring the I2C and blocking it for a certain amount of time, leaving me with a couple of channels set to the new PWM values, while the rest of the channels are still running on the old values. So, long story short: This driver can be merged as it looks good. However, unfortunately I won't be able to use it in this form, because of the issue that I just described. |
@mrusme The problem is that the built-in PWM driver API doesn't allow to synchronize the I would really appreciate, if you would provide a proposal for an extension of this PR. BTW, I already knew the problem of channel synchronisation and was thinking about to propose an extension of the built-in PWM driver API. |
I could imagine to add a member With this approach, the extender can be used as defined by the built-in PWM API, but the user has the option to use synchronized setting too. |
I'd rather prefer to merge a driver that is fit for a real-world use case, but it seems there is no easy solution for that. So I think it will be easier for everyone to propose changes to synchronized PWM output (atomic PWM setting? 😉) on top of the mainline tree. The driver works - extending the API to allow synchronized settings of multiple outputs is for another PR. |
while (!((mask >> shift) & 0x01)) { | ||
shift++; | ||
} | ||
*byte = ((*byte & ~mask) | ((bit << shift) & mask)); |
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.
Turns out the compiler will optimize this all away - neat!
Contribution description
This PR adds a driver vor the NXP PCA9685 16-channel, 12-bit PWM controller that is connected via I2C. Although the controller is optimized for LED control, the 12-bit resolution also allows the control of servos with a resolution of 4 us at 60 Hz refresh signal.
The following features of the PCA9685 are supported by the driver:
The driver interface is kept as compatible as possible with the peripheral PWM interface. The only differences are that
pca9685_
andUpdate:
The driver is also compatible with the PWM extension API in PR #10533 so that up to 64 PCA9685 PWM devices can be used as PWM extensions with the standard peripheral PWM interface.To get it merged soon, all PWM extension API code was removed.
Testing procedure
Please refer the test application in
tests/driver_pca9685
for an example on how to use the driverConnect a logic analyzer and execute the following tests:
Issues/PRs references
The PR is related to #10533 but does not depend on it. As long as moduleextend_pwm
is not enabled, it is working without #10533.