Skip to content
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 SH1106 OLED support #5787

Merged
merged 2 commits into from Jun 11, 2019
Merged

Add SH1106 OLED support #5787

merged 2 commits into from Jun 11, 2019

Conversation

datagrok
Copy link
Contributor

@datagrok datagrok commented May 5, 2019

Description

This patch adds rudimentary support for the SH1106 OLED driver IC, and some minor enhancements to better support my particular OLED module.

The SH1106 chip is quite similar to but not the same as the SSD1306 that drivers/oled/oled_driver.c was written to support. In particular:

  • Its internal ram for the display is 132x64 bits, compared to 128x64 for the SSD1306.
  • It supports only Page Addressing Mode, while the SSD1306 also supports Horizontal Addressing and Vertical Addressing. (oled_driver.c assumes Horizontal Addressing.)
  • It does not support hardware scrolling.

Regarding my particular OLED module:

I purchased a cheap 128x64 I2C OLED module claiming to use SSD1306, but it turned out to have an SH1106 instead. Recall that the SH1106 at 132x64 has a wider buffer than the physical display at 128x64. The vendor of my OLED module elected to connect the display such that the first two columns of display ram are not mapped to the display hardware. To accommodate this, I added #define OLED_COLUMN_OFFSET.

Since other full-featured graphics libraries exist that support many different chips, my goal for this patch was only to add basic support to QMK's oled_driver.c with a minimum of code changes.

It does not yet support 90 degree rotation (because I don't yet understand the algorithm implementing it), and it will probably never support scrolling (since that feature is missing from SH1106 hardware.)

This discussion in the Arduino forums helped me troubleshoot my OLED module enough to make these changes.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Keyboard (addition or update)
  • Keymap/layout/userspace (addition or update)
  • Documentation

Issues Fixed or Closed by This PR

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

@drashna
Copy link
Member

drashna commented May 5, 2019

Awesome!

However, if you could add to the OLED driver documentation, as well?

Also, @XScorpion2, if you wanted to double check the code?

@XScorpion2
Copy link
Contributor

yup, looking up SH1106 & reviewing now.

Copy link
Contributor

@XScorpion2 XScorpion2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to read the spec sheet a bit, but looks good. Only downside is that looking at the list of available commands in the specs, SH1106 won't be able to do 90 degree rendering as there is no way to specify a stopping column address to get the ram location you are writing at to wrap back to the beginning of the column, and advance to the next page.

drivers/oled/oled_driver.h Outdated Show resolved Hide resolved
drivers/oled/oled_driver.c Outdated Show resolved Hide resolved
@datagrok
Copy link
Contributor Author

datagrok commented May 7, 2019

Thanks very much for the code review @XScorpion2!

I've made the requested changes and a couple more small improvements:

  • Instead of defined(OLED_IC_SH1106), added a define OLED_IC that defaults to OLED_IC_SSD1306 but may be changed to OLED_IC_SH1106 or other future supported ICs.
  • Added a define OLED_COM_PINS that may be set to e.g. COM_PINS_ALTERNATING | COM_PINS_LR_REMAP in a keyboard's config.h when needed.
  • Updated docs to reflect changes.

I'm still having some issues with my 128x64 OLED display, however. I can't yet tell if these are bugs my changes introduced (and thus might affect SSD1306 users)... but I don't think they are. Still investigating.

  • I must set OLED_BLOCK_TYPE to uint_8 or uint_16 for the display to work properly; when set to uint_32 only the first four pages seem to update.
  • Text written to the last page (7) on my display seems to trigger a bug where the text wraps around and is written to the first page (0) instead, and no other pages get updated.

@XScorpion2
Copy link
Contributor

@datagrok hmm, those bugs do sound like they might cause issues with SSD1306 users. Let me review those areas of the code a bit closer. and I can also pull this down and test it on a few 128x32 boards at least.

Copy link
Contributor

@XScorpion2 XScorpion2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good to go

docs/feature_oled_driver.md Show resolved Hide resolved
drivers/oled/oled_driver.c Outdated Show resolved Hide resolved
@XScorpion2
Copy link
Contributor

XScorpion2 commented May 7, 2019

Ok, looking at the code, everything should be operating as expected as there really isn't any surprises. The page 7 issue might be the usage side causing issues, can you provide a link to your usage?
OLED_BLOCK_TYPE issue I'm not sure, going to check the assembly output for some of the bitshift operations as that could be an issue on AVR possibly.

Edit: Pulled it down and all my tests pass on device locally.

@datagrok
Copy link
Contributor Author

datagrok commented May 7, 2019

@XScorpion2 thanks again, and for testing my changes with your hardware! I added some commits to address the minor issues you mentioned.

The page 7 issue might be the usage side causing issues, can you provide a link to your usage?

Here it is. I'm rendering the QMK logo (3 pages), then three pages representing the key layout, then one page for the numlock status, and I should have one more page to use, but it breaks:

https://github.com/datagrok/qmk_firmware/blob/ssh1106_bug/keyboards/mitosis/keymaps/datagrok/keymap.c#L270L273

If you pull that code, note that you'd have to compile with OLED_DRIVER_ENABLE=yes (I do this at the command line, overriding what's in my rules.mk.)

Edit: I believe I've found my problem. The example code that outputs the num + caps + scroll lock status consumes the entire page, so I was adding a newline unnecessarily. Removing the newline makes it behave correctly and I can use all 8 pages. So please disregard the "page 7" problem I mentioned.

@datagrok
Copy link
Contributor Author

datagrok commented May 8, 2019

@drashna I've updated the docs, and @XScorpion2 has approved the majority of the changes.

One of the "issues" I mentioned in conversation above was my own fault; the other can be worked around.

If these minor changes made after approval look okay, I think this PR should be ready to merge? Thanks! 😁

Copy link
Member

@drashna drashna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@datagrok
Copy link
Contributor Author

@drashna who else needs to review this in order to allow it to merge? Or did you just want @XScorpion2 to approve the change introduced by those last two commits?

@drashna
Copy link
Member

drashna commented May 14, 2019

waiting on @jackhumbert or @skullydazed or others to review this.

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver
@datagrok
Copy link
Contributor Author

datagrok commented Jun 9, 2019

Rebased my work on master to incorporate @XScorpion2's improvements to the OLED driver from #6085.

@XScorpion2
Copy link
Contributor

👍 still approved

@drashna drashna merged commit e6a8113 into qmk:master Jun 11, 2019
drashna pushed a commit to zsa/qmk_firmware that referenced this pull request Jun 14, 2019
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
@datagrok datagrok deleted the sh1106_oled_support branch June 16, 2019 07:16
fdidron pushed a commit to zsa/qmk_firmware that referenced this pull request Jun 20, 2019
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
Timbus pushed a commit to Timbus/qmk_firmware that referenced this pull request Jun 23, 2019
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
doughsay pushed a commit to doughsay/qmk_firmware that referenced this pull request Aug 31, 2019
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
ridingqwerty pushed a commit to ridingqwerty/qmk_firmware that referenced this pull request Jan 10, 2020
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
JeffreyPalmer pushed a commit to JeffreyPalmer/qmk_firmware that referenced this pull request Feb 27, 2020
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
swamp09 pushed a commit to swamp09/qmk_firmware that referenced this pull request Mar 11, 2020
* modify oled_driver to support SH1106

also:
- improve mechanism to specify which OLED IC we use
- comment calc_bounds()
- give OLED_COLUMN_OFFSET a default value
- inline comment re: OLED MEMORY_MODE and SH1106
- update docs/feature_oled_driver.h for SH1106 support and related changes
- docs: OLED: note we have tested SSD1306 on ARM boards (per @XScorpion2)
- define out MEMORY_MODE when using SH1106 OLED driver

* document that SSD1306 128x64 on AVR works

Per @XScorpion2: qmk#5787 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants