-
Notifications
You must be signed in to change notification settings - Fork 8.3k
drivers: ssd16xx: Make voltage overrides optional #47712
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
Merged
carlescufi
merged 4 commits into
zephyrproject-rtos:main
from
andysan:ssd16xx_opt_overrides
Aug 16, 2022
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
40555f4
drivers: ssd16xx: Refactor activation
andysan 16a16c6
drivers: ssd16xx: Add a helper for uint8 writes
andysan d95f405
drivers: ssd16xx: Make voltage overrides optional
andysan 8d6a18f
drivers: ssd16xx: Make SSD1673 registers optional
andysan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
This makes contrast worse than with default values on GDEH0213B72 displays. Can you counter test or remove it for GDEH0213B72 displays?
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.
Do we want to use the values from the reference code or the values that produce better contrast here? I'm generally a bit reluctant to mess with these values since some of them (mainly voltages) presumably affect display reliability.
I can double check the values tonight and update to whatever we decide.
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.
OK, I think I know what's going on.
Broadly speaking, there are two generations of ssd16xx devices. These operate in subtly different ways, especially when it comes to partial refresh and some control registers (dummy line seems to be gen1 specific). I didn't really understand why some devices load two LUTs until recently. It seems like we are configuring most(?) gen 1 devices to use partial refresh using the second LUT. This is very strange though since we first configure the device for full refresh to clear the screen and then irreversibly enable partial refresh (but a lot of registers are incorrectly left in their full refresh state).
This causes two issues. The first problem is that there is no way to cause a full refresh to remove ghosting. As far as I understand, this will cause panel degradation. The second issue is that we potentially don't use the right voltages / timings for one of the LUTs. Looking at the example code from Waveshare, it seems like they got it wrong as well and don't correctly program the various voltages correctly when entering partial refresh.
The Waveshare example code use 0x30/0x0a for full refresh. Weirdly, the LUT table for partial refresh specifies 0x30/0x0a, but the code never writes that to the control registers but that's probably not a problem since they seem to correspond to the reset values. The old driver used 0x1a/0x08 which I have no idea where it came from.
I would suggest that we keep the new values since they are correct with respect to the LUT. You can find the corresponding example here: https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in13_V2.c
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 driver supports several similar controllers.
You probably mean the controllers on displays GDEH0213B1 (label HINK-E0213) and GDEH0213B72 (label HINK-E0213A22), both have been discontinued for a long time. Yes they use different controllers, also HINK-E0213 has no values in OTP at all. HINK-E0213A22 has values in OTP that produce very good results (but IIRC are too slow for reel board demo). Manufacturer for this EPDs (electrophoretic displays) is Good Display not Waveshare.
The driver makes full refresh at initialization. IMHO ghosting is not avoidable when using partial refresh (faster/simpler wave-forms) and the only correct way is to use setting from OTP (if they are available). "right voltages" depends also on the circuit and components.
Timings 0x1a/0x08 are for HINK-E0213, and come from Good Display sample code. And your are right, 0x30/0x0a are for HINK-E0213A22.
Uh oh!
There was an error while loading. Please reload this page.
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.
As far as I can tell, the devices I referred to as gen2 devices are mostly SSD168x and SSD1675B (but not SSD1675A) based panels. I think the only gen2 device we have in-tree is the GDEH0154D67 (HINK-E0154A07). Some of the SSD167x (at least SSD1673) seem to be gen 1 while the SSD1675B seems to be a gen 2. I think there might be a class of gen0 devices as well judging by the differences in the data sheets I have seen.
The important difference between the generations isn't the OTP. It's how the device looks up LUTs in the OTP and how to enable partial refresh. It seems like gen2 devices have introduced a new flag in
SSD16XX_CMD_UPDATE_CTRL2that enables what is referred to as "mode 2". Gen 1 devices seem to use the same bit for something else, but it isn't clear what it does from the datasheet. Gen 1 devices, similar to UC81xx devices, seem to require software overriding the LUT to enable fast partial / differential updates.I think one of the reasons they made this change is that it makes it possible for gen2 devices to use a single master activation to load either a full refresh or a partial refresh LUT from OTP by looking at the mode bit.
Yes, it does make a full refresh at initialisation. However, the manual for many of these panels specify that a full refresh is needed at a regular interval. Typically daily or after a fixed number of partial updates. This is currently not possible.
As for right voltages, the my understanding is that VCOM/VGH/VSH/VSL values are strongly dependant on the panel, LUT, and the frame rate (controlled by dummy line and friends). A higher voltage differential between the back and the front of the panel results in quicker movement, which means that a shorter update can be achieved. The LUT tables assume a specific frame rate and specifics voltages. If these don't match, you potentially end up driving the pixels too hard and/or too long which can result in permanent damage.
In this case, we seem to be using the VCOM voltage (0x26 / -0.95V) from the partial refresh instead of a full refresh (0x55 / -2.1V).
So, should we go with the values matching the panel 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.
Let me test it again please.
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 have always seen variation in contrast among the same display types. It seems to be higher with these values, though I no longer have access to significant numbers of panels for an experiment.