Skip to content

Commit 217cc51

Browse files
authored
Add some direct screen buffer writer methods to SSD13xx (#223)
1 parent 6f4dcdb commit 217cc51

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

devices/Ssd13xx/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,61 @@ The following connection types are supported by this binding.
2727

2828
- [X] I2C
2929
- [ ] SPI
30+
31+
## Usage notes
32+
33+
There are two groups of drawing methods.
34+
35+
1. Various specialized drawing methods allowing to draw on screen pixel-by-pixel, like:
36+
- ````DrawPixel(...)````: draws one pixel
37+
- ````DrawHorizontalLine(...)````: draws a horizontal line
38+
- ````DrawVerticalLine(...)````: draws a vertical line
39+
- ````DrawFilledRectangle(...)````: draws a filled rectangle
40+
- ````DrawBitmap(...)````: draws a bitmap
41+
- ````DrawString(...)````: draws a string with preset font
42+
43+
Using these methods you do not need to care about any technique the driver uses to display
44+
your drawing instructions.
45+
46+
2. Methods allowing to modify screen content by blocks of internal representation (screen buffer), like:
47+
- ````DrawDirectAligned(...)````: overwrites screen buffer with given content
48+
- ````ClearDirectAligned(...)````: clears out (with 0x00) given part of screen buffer
49+
50+
These methods allow faster (~100 times) display access but with some constraints.
51+
- bitmaps handed over here must be in appropriate format (see SSD13xx docs for "GDDRAM" and "Horizontal addressing mode").
52+
- no bit operations occure with existing buffer data (with pixels drawn via other means), the new data will overwrite the pixels "below" newly drawed content.
53+
- the "y" coordinate and the bitmap height must be byte aligned with screen buffer (again, see above docs)
54+
55+
The use of two groups can be freely mixed (e.g. display text via ````DrawString(...)```` and displaying an image below via ````DrawDirectAligned(...)````)
56+
57+
Examples for 1. can be found in ````samples```` folder.
58+
59+
Example for 2. follows here.
60+
61+
````csharp
62+
// There are superb online helpers like the one below which are able to
63+
// create an appropriate byte array from an image in code use ready format.
64+
// https://www.mischianti.org/images-to-byte-array-online-converter-cpp-arduino/
65+
// On the site above use these settings to get bytes needed here:
66+
// - "plain bytes"
67+
// - "vertical - 1 bit per pixel"
68+
var buffer = new byte[] { ... };
69+
var width = 16;
70+
var height = 16;
71+
72+
// instantiation example
73+
var ssd1306 = new Ssd1306(
74+
I2cDevice.Create(
75+
new I2cConnectionSettings(
76+
1,
77+
Ssd1306.DefaultI2cAddress,
78+
I2cBusSpeed.FastMode)),
79+
Ssd13xx.DisplayResolution.OLED128x64);
80+
81+
// this line sends the image data to the screen
82+
ssd1306.DrawDirectAligned(x, y, width, height, buffer);
83+
84+
// this one wipes its place to blank
85+
ssd1306.ClearDirectAligned(x, y, width, height);
86+
87+
````

devices/Ssd13xx/Ssd13xx.cs

+66
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,72 @@ protected SpanByte SliceGenericBuffer(int start, int length)
145145
return _genericBuffer;
146146
}
147147

148+
/// <summary>
149+
/// Copies buffer content directly to display buffer.
150+
/// Y and height must be byte aligned because buffer will
151+
/// be copied without any logical operations on existing content.
152+
/// </summary>
153+
/// <param name="x">The x coordinate on the screen.</param>
154+
/// <param name="y">The y coordinate on the screen.</param>
155+
/// <param name="width">Width of buffer content in pixels.</param>
156+
/// <param name="height">Height of buffer content in pixels.</param>
157+
/// <param name="buffer">Data to copy. Buffer size must be equal to height * width / 8.</param>
158+
public void DrawDirectAligned(int x, int y, int width, int height, byte[] buffer)
159+
{
160+
if ((y % 8) != 0)
161+
{
162+
throw new ArgumentException("Y must be aligned to byte boundary.");
163+
}
164+
if ((height % 8) != 0)
165+
{
166+
throw new ArgumentException("Height must be aligned to byte boundary.");
167+
}
168+
169+
var dataHeightInBytes = height / 8;
170+
if ((dataHeightInBytes * width) != buffer.Length)
171+
{
172+
throw new ArgumentException("Width and height do not match the bitmap size.");
173+
}
174+
175+
var genericBufferIdx = y / 8 * Width + x;
176+
var srcIdx = 0;
177+
for (int i = 0; i < dataHeightInBytes; i++)
178+
{
179+
Array.Copy(buffer, srcIdx, _genericBuffer, genericBufferIdx, width);
180+
srcIdx += width;
181+
genericBufferIdx += Width;
182+
}
183+
}
184+
185+
/// <summary>
186+
/// Clears portion of display via writing 0x00 directly to display buffer.
187+
/// Y and height must be byte aligned because bytes will
188+
/// be written without any logical operations on existing content.
189+
/// </summary>
190+
/// <param name="x">The x coordinate on the screen.</param>
191+
/// <param name="y">The y coordinate on the screen.</param>
192+
/// <param name="width">Width of area in pixels.</param>
193+
/// <param name="height">Height of area in pixels.</param>
194+
public void ClearDirectAligned(int x, int y, int width, int height)
195+
{
196+
if ((y % 8) != 0)
197+
{
198+
throw new ArgumentException("Y must be aligned to byte boundary.");
199+
}
200+
if ((height % 8) != 0)
201+
{
202+
throw new ArgumentException("Height must be aligned to byte boundary.");
203+
}
204+
205+
var dataHeightInBytes = height / 8;
206+
var genericBufferIdx = y / 8 * Width + x;
207+
for (int i = 0; i < dataHeightInBytes; i++)
208+
{
209+
Array.Clear(_genericBuffer, genericBufferIdx, width);
210+
genericBufferIdx += Width;
211+
}
212+
}
213+
148214
/// <summary>
149215
/// Draws a pixel on the screen.
150216
/// </summary>

0 commit comments

Comments
 (0)