für ein neues Projekt muss ich das genannte Display in Betrieb nehmen und bin etwas verwirrt was das Datenblatt betrifft, bezogen auf das was ich beobachte.
Nun zu meinem Verständnisproblem:
Laut SSD1322 Datenblatt werden immer 4 Bit zu einem Pixel abgebildet (16 Graustufen).
1 Beobachtung:
Falls dies wirklich so wäre, dann müsste ich ja nur 64 Byte übertragen um alle 128 Pixel in einer Zeile anzusteuern. Dem ist jedoch nicht so.
Ich muss 128 Byte senden.
2 Beobachtung:
Ich habe den Eindruck, dass ich mehr als nur 16 Graustufen darstellen kann.
Könnte es sein, dass Newhaven 2 Segmente zu einem Pixel zusammengefasst hat? Was die 1 Beobachtung erklären würde.
Im angehängten Code habe ich mal 5 Fälle abgebildet um es mal zu vergleichen:
Balken mit 10px Höhe, Bit 3:0, Pixel = 0x0F
Balken mit 10px Höhe, Bit 7:4, Pixel = 0xF0
Graustufen 0-127
Graustufen 128-255
Graustufen 0-16 gleichzeitig auf Bit 7:4 & Bit 3:0
Habe mal versucht so gut wie möglich ein Foto zu machen, die Nr. entsprechen den genannten Fällen.
Hoffe mir kann von euch jmnd auf die Sprünge helfen, denn irgendwie ergibt das alles keinen Sinn für mich.
Statt irgendwelche gleichförmigen Balken auszugeben, schreib' doch einfach hintereinander die Werte 0, 1, 2 etc. bis 255.
In einer weiteren Zeile: Schreibe abwechselnd 0x0f und 0xf0.
Gut. Und, wie sieht das Ding aus, wenn Du nichts anderes machst als
"data(0xf0); data(0x0f);" 32 mal hintereinander aufzurufen?
Genau so wie Balken 1 & 2. Kein Unterschied.
Aber das sieht man doch schon auf dem Bild.
Ob ich nun jedes Byte immer umswitche oder mit 0x0F 10x128px zeichne und dann nochmal 10x128px mit 0xF0, macht doch kein Unterschied.
Mir fehlt der Zusammenhang zwischen Byte und dem GDDRAM.
Denn anscheinend ist z.B. 0xF0 nicht für 1px den dann wäre es ja hell weiß,
dafür muss ich das Byte jedoch auf 0xFF setzen.
edit:
Weiterhin ist mir grad aufgefallen. Einzelnes Pixel kann ich gar nicht übertragen, es müssen immer 2 Byte sein, sonst übernimmt der SSD1322 die Daten nicht.
Gut. Und, wie sieht das Ding aus, wenn Du nichts anderes machst als
"data(0xf0); data(0x0f);" 32 mal hintereinander aufzurufen?
Genau so wie Balken 1 & 2. Kein Unterschied.
1
for(uint8_tj=0;j<128;j++)
2
{
3
if(j%2)
4
ssd1322_data(0x0F);
5
else
6
ssd1322_data(0xF0);
7
}
Das Ergebnis ist einfach ein grauer Streifen.
Edit:
Mal abgesehen von der Grauabstufung, finde ich es halt seltsam das laut DB 4 Pixel mit 2 Byte angesprochen werden sollten. Übertrage ich jedoch 2 Byte [0xFF, 0xFF] dann leuchten lediglich 2 Pixel.
Aber ich weiß auch net so recht was du da versuchst.
Es geht mir nicht um die Reihenfolge der Bytes, sondern um die Zuordnung innerhalb eines Pixels.
Ist ja wohl klar, das da immer on/off kommt, wenn ich abwechselnd 0 oder F sende.
Ich möchte jedoch gern die Grauabstufung verstehen, da diese anscheinend nicht zum SSD1322 DB passt.
Nach weiteren Tests bin ich nun zu folgenden Erkenntnissen gekommen, für alle die es interessiert und evtl. mal auf das gleiche Probleme stoßen.
Bezogen auf das Newhaven Display, die haben anscheinend ihre eigene
Suppe mit dem SSD1322 gekocht.
1 px entspricht 1 Byte
Es müssen mindestens 2 Byte übertragen werden, bevor diese übernommen werden.
Die einzelne Inkrementierung des unteren sowie oberen Nibbles resultiert in gleichen Graustufen (nicht volle Helligkeit).
Test 1:
0x00, 0x01, 0x02 ... 0x0F
Test 2:
0x00, 0x10, 0x20 ... 0xF0
Die Reihenfolge:
0x00, 0x01, 0x02 ... 0x0F, 0x1F, 0x2F ... 0xFF
(erst unteres Nibble bis max., dann das obere Nibble inkrementieren) hat beim Übergang von 0x0F zu 0x1F einen zu großen Helligkeitssprung.
Durch das gleichzeitige Inkremetieren des unteren sowie oberen Nibbles erhält man eine schöne Grauabstufung. Wobei der Wert 0x11 wie schwarz aussieht, mit der default grayscale table des SSD1322.
(siehe Bild)
Testbild wurde wie folgt generiert (unterer weiße Bereich dient zur Kontrolle der max. Helligkeit)
1
/* 32 px Höhe */
2
for(uint16_ti=0;i<32;i++)
3
{
4
/* 16 Graustufen */
5
for(uint16_tj=0;j<16;j++)
6
{
7
px=(j<<4)|j;
8
9
/* 8 px Breite */
10
for(uint16_tk=0;k<8;k++)
11
{
12
ssd1322_data(px);
13
}
14
}
15
}
16
17
/* 1px Linie schwarz */
18
for(uint16_ti=0;i<128;i++)
19
ssd1322_data(0x00);
20
21
/* 31 x 128 px weiß */
22
for(uint8_ti=0;i<31;i++)
23
{
24
for(uint8_tj=0;j<128;j++)
25
{
26
ssd1322_data(0xFF);
27
}
28
}
Somit ist das Problem für mich erstmal gelöst, wäre einfacher gewesen hätte sich Newhaven daran gehalten wie es eigentlich mit dem SSD1322 sein sollte.
P.S.
Das die column Koordinate = 0x1C, X=0 enspricht liegt daran, dass Newhaven aufgrund des Layouts einfach die vorderen Segmente nicht verwendet:
Ist der auf Deinem Bild zu sehende graue Rand rechts und um den unteren
weißen Balken herum ein Artefakt Deiner Photographie?
Der "graue Rand" der aussieht wie Anti aliasing ist bedingt durch die Kamera.
Das einzige was ist, die erste Zeile vom weißen Rechteck (rote Pfeile auf Bild) ist etwas dunkler als 0xFF.
Dies liegt aber eher an den SEG / COM Treibern.
Spielt für unsere Anwendungsfall keine große Rolle, da ich eher selten soviel weiße Fläche darstellen werde, dass da die Last so hoch wird.
Na dann .. gratuliere: Du hast eine Erklärung für das vom Datenblatt abweichende Verhalten gefunden und offenkundig auch eine für Dich verwendbare Lösung.
Gut zu wissen, daß derartige Displays auch "anders" sein können.