-
-
Notifications
You must be signed in to change notification settings - Fork 39.8k
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: Implemented i2c bitbang driver #12616
base: develop
Are you sure you want to change the base?
Conversation
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.
Did not try to check the actual I2C implementation against the spec, but noticed some imperfections around.
Would prefer that this was implemented more like how other drivers are. Eg: qmk_firmware/common_features.mk Lines 373 to 399 in f93ad79
|
Could you clarify which parts of the code you're referring to?
So I would have to refactor all that somehow, if that's the road we want to go down on, but I would need some clarification as to what the refactor would look like.
I considered it out of scope of this PR to fix this bug, but the above provided example driver has a single .h file, and multiple .c file implementations. Merging those .h files would mean that either those idiosyncrasies have to be cleaned up first, or I would have to have #ifdefs in the common .h file. |
From the API standpoint, looks like there should be two layers of the I2C driver API:
|
@sigprof I agree with all that, I absolutely would prefer if i2c driver api was all uniform, and I want to help make that a reality. However, the question is should this specific PR be gated on all that cleanup? I estimate the effort to get the i2c drivers uniform is at least twice as much as I spent developing this i2c bitbang driver, if not more, and I would like to get this in so my keyboards can use it. |
No, keep this separate. Much easier to review normalisation passes if that's all they include. Multiple bus peripherals is already on my radar, I'd prefer if we discussed this before any work is embarked on. |
@drashna Could you clarify, are you still waiting to see changes on this PR, given my comments after your review? |
Ideally, the filename would be /drivers/(avr|chibios)/i2c_master_(name).c But you're right, that would require chaning instances of i2c_master.c being added. In that case, Eg:
And
|
Thank you for your contribution! |
e4af430
to
99b86f4
Compare
I have rebased, and retargetted the changes to develop. (+Made it more correct for Xmega, and 3-byte PC AVRs.) (Not yet tested after rebase) Some of the possible solutions I see:
This, implemented in combination with your suggestion on how to get i2c_master.c compiled in.
I'm still leaning towards 6) but maybe there's a better 7th option I don't see. I'm happy to implement any solution to get this PR through, but we have to deal in some way with the |
Oh, there's another issue: The linter PR tester is wanting to screw up my nicely formatted inline assembly to the point it's totally unreadable. Would it be possible to maintain my formatting of the inline assembly code? I'm happy to apply all the other C code changes the linter suggests, but the inline assembly is the way it is for readability, and what the linter formatter does makes no sense. |
Ignore linter. :( |
You can try to surround some parts of the source with these special comments: // clang-format off
/* ... some code which would be screwed up by clang-format ... */
// clang-format on |
d316724
to
dc103c3
Compare
Rebased again on top of develop, to fix issue with some files that always appeared modified due to line endings, and added small fix to performance regression that was due to not detecting correctly the AVR's ARCH. (i.e. XMEGA vs AVR8) Here for fresh waves, tested on atmega32u4: @sigprof Thanks, clang-format helped, there are no more issues with the linter. |
971c45c
to
a67391b
Compare
Rebased to fix conflict |
a67391b
to
190c7e7
Compare
Implemented 16-bit address register read/write functions, that newly landed in QMK develop, |
Unfortunately, between the time that this PR was started, and now, a lot of things have changed. If you could, reorganize the files so that the drive files are in And would prefe that they're named how the other drivers are. Eg. That way, the drivers are all over the place, and is more obvious which is which. |
I've been keeping this, and the alternate version of this PR ( #14183 ) up to date with changes in develop, so I followed the move of the native i2c implementation to platforms (cause I had to do file moves/renames on the native implementation) , and I also implemented the 16-bit address register access functions. Please take a look at my alternate PR too, there I have renamed the Regarding moving it into /platforms: I have a single |
Can I just ask one simple question? What does this PR solve? There's no indication of intent in the description of this or in #14183. I2C is a multi-peripheral bus, and the pins for dedicated I2C hardware peripherals on AVR and ARM are both known at board design time. If it ends up being used in multiple places, then perhaps it's worth revisiting the implementation in core then, but at this stage if it's for one keyboard I don't see the point. |
@tzarc Yes, the intent is mostly to cater to poor design, and I believe this is valuable enough to include in core, let me argue:
|
This bitbang driver allows the user to use any two gpio pins for I2C communication. To enable set the makefile variable I2C_DRIVER=bitbang Implements fast mode and standard mode (using fast mode by default). To select standard mode #define I2C_BITBANG_STANDARD_MODE in config.h On STM32 devices with RT clock, this code will achieve very efficient timings, achieving above 390kHZ in fast mode. On AVR devices running at 16MHz 400kHz has can be achieved in fast mode, as long as there are no interrupts, and clock stretching is not requested by the device. On STM32 devices without an RT timer, only 25kHz can be achieved with the current implementation. some parts Co-authored-by: Sergey Vlasov <[email protected]>
190c7e7
to
df719ab
Compare
Rebased to resolve conflicts |
Description
This bitbang driver allows the user to use any two gpio pins for I2C communication.
To enable set the makefile variable I2C_DRIVER=bitbang
Implements fast mode and standard mode (using fast mode by default).
To select standard mode #define I2C_BITBANG_STANDARD_MODE in config.h
On STM32 devices with RT clock, this code will achieve very efficient timings, achieving above 390kHZ in fast mode.
On other devices i2c communication will be significantly slower.
On AVR devices 168kHz has can be achieved in fast mode.
On STM32 devices without an RT timer, only 25kHz can be achieved with the current implementation.
Please see here for logic analyzer plots: https://imgur.com/a/NnnSNx4
Types of Changes
Checklist