Wrong Init Routine for SSD1322 ? / NHD-2.7-12864WD
See original GitHub issueRPi3 B+ Linux 4.9.79-v7+ #1086 armv7l GNU/Linux
I got this new display recently for a project and have been trying to get started with it and luma.oled. Datasheet here: https://www.mouser.com/ds/2/291/NHD-2.7-12864WDY3-1116258.pdf It has an SSD1322 controller that I am trying to access via SPI on the raspi.
config is as such:
--display=ssd1322
--interface=spi
--spi-device=0
--spi-port=0
--gpio-reset=23
--gpio-data-command=24
--mode=RGB
Here is a video a first trial where it kind of worked, but now it doesn’t react at all to any of the examples. It is clearly not initialized and driven in the right way. The rotating cube was the only example doing anything surprisingly for some moments, unclear why. https://www.youtube.com/watch?v=jjIOZmPjGdw
Here is the recommended init from the datasheet:
void NHD12864WDY3_Init(void){
digitalWrite(RES, LOW); //pull /RES (pin #16) low
delayUS(200); //keep /RES low for minimum 200μs
digitalWrite(RES, HIGH);//pull /RES high
delayUS(200); //wait minimum 200μs before sending commands
writeCommand(0xAE); //display OFF
writeCommand(0xB3); //set CLK div. & OSC freq.
writeData(0x91);
writeCommand(0xCA); //set MUX ratio
writeData(0x3F);
writeCommand(0xA2); //set offset
writeData(0x00);
writeCommand(0xAB); //function selection
writeData(0x01);
writeCommand(0xA0); //set re-map
writeData(0x16);
writeData(0x11);
writeCommand(0xC7); //master contrast current
writeData(0x0F);
writeCommand(0xC1); //set contrast current
writeData(0x9F);
writeCommand(0xB1); //set phase length
writeData(0xF2);
writeCommand(0xBB); //set pre-charge voltage
writeData(0x1F);
writeCommand(0xB4); //set VSL
writeData(0xA0);
writeData(0xFD);
writeCommand(0xBE); //set VCOMH
writeData(0x04);
writeCommand(0xA6); //set display mode
writeCommand(0xAF); //display ON
}
In luma/oled/device.py in the SSD1322 init function there are many differences to this, so I am wondering if this is the culprit of my problems?
self.command(0xFD, 0x12) # Unlock IC
self.command(0xA4) # Display off (all pixels off)
self.command(0xB3, 0xF2) # Display divide clockratio/freq
self.command(0xCA, 0x3F) # Set MUX ratio
self.command(0xA2, 0x00) # Display offset
self.command(0xA1, 0x00) # Display start Line
self.command(0xA0, 0x14, 0x11) # Set remap & dual COM Line
self.command(0xB5, 0x00) # Set GPIO (disabled)
self.command(0xAB, 0x01) # Function select (internal Vdd)
self.command(0xB4, 0xA0, 0xFD) # Display enhancement A (External VSL)
self.command(0xC7, 0x0F) # Master contrast (reset)
self.command(0xB9) # Set default greyscale table
self.command(0xB1, 0xF0) # Phase length
self.command(0xD1, 0x82, 0x20) # Display enhancement B (reset)
self.command(0xBB, 0x0D) # Pre-charge voltage
self.command(0xB6, 0x08) # 2nd precharge period
self.command(0xBE, 0x00) # Set VcomH
self.command(0xA6) # Normal display (reset)
self.command(0xA9) # Exit partial display
self.contrast(0x7F) # Reset
Here is an edit I attempted but its still not working at all, the display is not activated and I am unsure about some additional steps in the initialization that I got rid of.
self.command(0xAE) # Display off (all pixels off) self.command(0xA4)
self.command(0xB3, 0x91) # Display divide clockratio/freq was: self.command(0xB3, 0xF2)
self.command(0xCA, 0x3F) # Set MUX ratio
self.command(0xA2, 0x00) # Display offset
self.command(0xAB, 0x01) # Display start Line was: self.command(0xA1, 0x00)
self.command(0xA0, 0x16, 0x11) # Set remap & dual COM Line was: self.command(0xA0, 0x14, 0x11)
self.command(0xC7, 0x0F) # Master contrast (reset)
self.command(0xC1, 0x9F) # ADDITION set contrast current
self.command(0xB1, 0xF2) # Phase length was: self.command(0xB1, 0xF0)
self.command(0xBB, 0x1F) # Pre-charge voltage was: self.command(0xBB, 0x0D)
self.command(0xB4, 0xA0, 0xFD) # ADDITION set VSL
self.command(0xBE, 0x04) # Set VcomH was: self.command(0xBE, 0x00)
self.command(0xA6) # Normal display (reset)
self.command(0xAF) # Exit partial display self.command(0xA9)
The question is, do we need to differntiate this display from the other SSD1322 driven ones, is my display “special” or broken or is this init routine generally wrong for the SSD1322 controller or did I do something wrong with SPI on the RPi… I am not very clear on how fast we can drive this display (10Mhz? it sometimes worked for a few seconds at a time as seen in the video with 16Mhz)
I am glad about any pointers you can give me to get this display running and if I/we can find a solution I’ll send a pull request if necessary.
Issue Analytics
- State:
- Created 6 years ago
- Comments:35 (8 by maintainers)
Top GitHub Comments
I’ve been having some issues with the same 2.7 New Haven display. Initially the modified _nhd class seemed to work. But grey ramps were messed up and anitalised text looked seriously wonky. I see that the class was writing out byte values rather than nibble encoded 4bit / 16 grey levels. After some experimentation it looks very much like there’s something interesting going on here.
I /think/ every other nibble controls the alternate scan of the pixel. Very strange. Anyway if I write out data for wxh (rather than wxh/2) and duplicate every pixel into both the upper and lower nibble everything looks great - the ramps now display correctly and text renders as expected - where’s previously values like 240 (prior to send to device) would snap to an incredibly low display value which looks effectively black).
If I write a zero nibble then a 4 but it displays dim but full screen. Same if I write a high nibble then zero. So clearly it needs 8bits per pixel. But it’s doing something with both the top and bottom nibble for that same pixel- seemingly it’s a dual scan on the pixel which I don’t get with the mechanics of how oleds work for precharge cycles etc. but nonetheless it appears to work a /lot/ better.
So sorry to reopen this but I think the nhd init routine / display routines are still wrong for things that aren’t pure black / white.
this is the working ramps. I can upload more images to show the diffs as needed.
I will try and tidy up the copious init routine hacks and submit a PR.
George
If pins 19 and 20 weren’t tie to logic 0 (usually ground) and VDD, then those pins are floating. You won’t have a guarantee of the interface mode. Re-wire your setup and the only pins you can leave not counted are the one labeled N.C. (3, 9, 15, and 18). All VSS pins must be connect to ground.
Shoot me an email if you need further assistance.