-
Notifications
You must be signed in to change notification settings - Fork 8
Added the ST7735 Display Driver #2
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
Conversation
Oh yeah, I fixed all the stuff so it passes on Travis too. |
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.
Thank you for working on this! I made a number of comments because the Arduino driver isn't structured very well. I think we can add clarity to this driver and simplify if for everyone with a little more work.
adafruit_st7735.py
Outdated
|
||
_INIT_R4_BLACK = ( | ||
b"\x36\x01\xC0" # _MADCTL Rotate to Landscape Mode | ||
) |
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.
Having all of these bytearrays in one file will take more memory that strictly necessary. I'd rather have multiple files with some duplication.
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, that makes sense.
adafruit_st7735.py
Outdated
def __init__(self, bus, *, width, height): | ||
super().__init__(bus, _INIT_SEQUENCE, width=width, height=height, colstart=2) | ||
init_sequence = _INIT_R1 + _INIT_R2_GREEN + _INIT_R3 |
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.
Adding all of the init sequences together will briefly make a duplicate allocation. I don't think it is necessary.
Instead, we can have them as mutable bytearrays that we can patch in the constructor.
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’ll look into that. I’m unfamiliar with the term.
adafruit_st7735.py
Outdated
_INIT_R2_GREEN_160X80 = ( | ||
b"\x2a\x00\x00\x00\x4F" # _CASET XSTART = 0, XEND = 79 | ||
b"\x2b\x00\x00\x00\x9F" # _RASET XSTART = 0, XEND = 159 | ||
) |
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.
These _INIT_R2 aren't needed because CircuitPython will reset them before sending any data.
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’ll test without these and remove them if they work the same.
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 tested it and now I'm getting what you're saying.
adafruit_st7735.py
Outdated
def __init__(self, bus, *, width, height): | ||
super().__init__(bus, _INIT_SEQUENCE_B, width=width, height=height) | ||
|
||
class MINI160X80(displayio.Display): |
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'd like to see a separate library for Adafruit display products because it's the board and LCD pair that defines displayed resolution. The ST7735 functionality is separate of that. Once that is removed only ST7735B and ST7735R will remain. Then, in the adafruit display repo we can be very explicit about the setup on a per product number ID rather than tab color.
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 I understand what you mean. Does that mean the rotation and color mode can still be passed after initialization?
I think you'll like how it is much better. I know I do. |
adafruit_st7735/st7735b.py
Outdated
b"\xE0\x10\x09\x16\x09\x20\x21\x1B\x13\x19\x17\x15\x1E\x2B\x04\x05\x02\x0E" # _GMCTRP1 Gamma | ||
b"\xE1\x90\x0B\x14\x08\x1E\x22\x1D\x18\x1E\x1B\x1A\x24\x2B\x06\x06\x02\x0F\x0A" # _GMCTRN1 | ||
b"\x2a\x00\x02\x00\x81" # _CASET | ||
b"\x2b\x00\x02\x00\x81" # _RASET |
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 we don't need to set the column and row, because that is going to be done by displayio every time it actually sends anything to the display (the Arduino driver needs it, because it only sets the column and row once at the beginning, and then sends the whole screen every time).
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.
Good catch. Fixed.
Should the example be updated to use TileGrid instead of Sprites and x,y instead of position? |
@jerryneedell, I updated the example in this PR to use TileGrid. I just went ahead and updated it in the Readme as well. |
Since I just got a TFT Mini Breakout, I wrote an example for that too. |
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.
It's looking way better! Thank you for your hard work on this. I added one comment about the init kwarg inline.
How do you feel about splitting this into two libraries? One for the ST7735 and one for the ST7735R. They really are separate driver chips even though the names are almost the same.
adafruit_st7735/st7735r.py
Outdated
"""ST7735 driver for ST7735R""" | ||
def __init__(self, bus, *, init=None, **kwargs): | ||
""" | ||
:param bytes init: (Optional) An extra init sequence to append (default=None) |
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'm not a fan of this init argument because it leaks the binary blob init stuff. Display already has a rotation kwarg that can be used for rotation. (It's very slow for OnDiskBitmaps atm but we can improve it later.) If we also need a toggle for RGB or BGR then let's add it explicitly rather than generically.
By using Display for rotation we align our display memory accesses with the native refresh direction and make it easier to make updates tear-free in the future.
Advanced users can always use the display bus themselves to send extra commands too.
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 the rotation doesn’t work for some displays like the 3.5 FeatherWing. Also, this was written before I dug into the actual CP code and now that I’m more comfortable with that, making some changes shouldn’t be a problem.
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.
So far in my testing, only a few displays needed to be initialized as BGR. The only driver that was complicated though was this one. This particular parameter is a little messy since it's also combined with the display rotation. There's 3 ways of doing this that I can see:
- Add a BGR parameter to the init function in the driver itself that adds an init code with the default rotation but sets BGR if true and make use of the rotation option in the driver.
- Make changes to the way the colors are converted if this flag is toggled when they are 565 encoded as BGR instead of RGB. I don't know if colors are always converted, so if they're not this may not work.
- Attempt to run the command inside of CP with default rotation if BGR is passed. This option could get messy for non-MIPI displays.
Personally my favorite option is #1 because the change is only in the driver. #2 is my second favorite, but I'm not sure if it will always work. #3 seems a bit sketchy and doesn't provide much benefit over #1, and is less flexible.
Another idea is we could always start with option #1 and implement option #2 after 4.0 stable is released.
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 like 1 but want to avoid MADCTL for rotation because it only impacts the memory access orientation, not screen refresh. If we always allow displayio to rotate "in software" rather than using MADCTL we can ensure our memory updates align with screen updates. This also means we can know in what direction the hardware scrolling of the display occurs.
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 agree, which is why I’m only using MADCTL for BGR vs RGB and leaving rotation at default.
Tested with a 160x128 display, works well. |
As we chatted about, let's split this into two repos because the ST7735 and ST7735R chips are separate ICs and datasheets. That way the driver structure for displays matches non-displays. |
Hi @tannewt, should the new Repo be named Adafruit_CircuitPython_ST7735R then? I'm just wondering if this may be more confusing to users who aren't as familiar with the differences between the R and non-R. Before starting on this, I wouldn't have known the difference. I'm thinking we should get rid of the non-R code and just keep this repo with the R code (since that's what the displays use) so that it's closer to the Arduino setup. Also, if it sits better with you, we could either rename this repo to the R version or create a repo with the R on it and delete this one. |
I've created a new repo for the R variant: https://github.com/adafruit/Adafruit_CircuitPython_ST7735R Since we may want to use this name in the future it's better to create a new repo. Renaming this one causes a redirect from here to the new name. While I agree the naming is potentially confusing I think awareness of this detail is needed for all drivers named after the IC. I don't expect many customers to work at this level anyway. We're moving to a product driver model where Adafruit customers will either grab example code from the product guide or use a library like FeatherWing that does it for them. Thanks for sticking with me! |
Thanks for making that. I’ll separate this out tonight and create an additional PR for the R version. |
The problem here is that there are really two components here — the IC, and the display itself. While the IC is the same in all those versions, the actual display used, and more importantly, the way they are wired differs. For most other displays this is not a problem, because you only have one "standard" wiring per display size (so you can infer options like RGB/BGR from the size), but with the ST7735 modules there is more variety for some reason. I'm still unsure if we don't simply want to have a "variant" parameter for creating the display object. |
@deshipu I totally agree. I don't think this library should handle the wiring side except that it exposes constructor arguments to use. The modules themselves can have libraries or example code for those details. It doesn't belong in this library. Enforcing this separation ensures we document the options well and make it easier to use the IC with other displays. |
Ok, separation has been done. All of the R code is in the other Repo and is the preferred once since that's what the Adafruit Displays use. This is now the non-R ST7735 driver which is untested since I am not aware of any ST7735 (non-R) displays to test this on. In theory it should work. I'm not sure if we want to release this as is and if somebody does come across a display that this is for and it doesn't work, test it then? |
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.
Thanks again! You rule!
I have subclassed all of the ST7735 variations and this fixes #1. There will be a separate PR for the ST7789.