Skip to content

Commit f7a9399

Browse files
Adding generic display driver (#118)
* Adjusting for generic graphic drivers * adjusting * adjusting to remove warnings * adjusting pragma * fixing pragma * Add exclude rules for enums @Ellerbach check this out on how to exclude enums that are not used in native. With this they are not added to the stubs. I'm not familiar with the code, so please check if any of these should indeed be there. And, of course, do add all the others that don't need to be there. --------- Co-authored-by: José Simões <[email protected]>
1 parent 0d0ba15 commit f7a9399

File tree

11 files changed

+599
-169
lines changed

11 files changed

+599
-169
lines changed

README.md

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,176 @@ Note that depending on your target, especially for ESP32, you may have to setup
5858

5959
As you can see it is possible as well not to define the backlight pin. It is the same for the rest pins. Both can be set to -1. Note that in most of the cases, both are connected and needed. In the case of the M5 Stick, the backlight pin is managed thru an AXP192. If you don't switch on the backlight pin, your screen will always be black. It is important to check how this pin can be switched on.
6060

61+
## Using generic graphic SPI drivers
62+
63+
It's now possible to use generic graphic SPI drivers. It does require to build an image with the `Generic_SPI.cpp` driver. Once the image is flashed on the device, you can give the driver commands directly from a class in managed code. When building with a specific driver, the generic driver will be ignored even if you provide it.
64+
65+
Here is an example based on the ST7735S driver, we've been using enum for the registers:
66+
67+
```csharp
68+
private enum St7735
69+
{
70+
NOP = 0x00,
71+
SOFTWARE_RESET = 0x01,
72+
POWER_STATE = 0x10,
73+
Sleep_Out = 0x11,
74+
Invertion_Off = 0x20,
75+
Invertion_On = 0x21,
76+
Gamma_Set = 0x26,
77+
Display_OFF = 0x28,
78+
Display_ON = 0x29,
79+
Column_Address_Set = 0x2A,
80+
Page_Address_Set = 0x2B,
81+
Memory_Write = 0x2C,
82+
Colour_Set = 0x2D,
83+
Memory_Read = 0x2E,
84+
Partial_Area = 0x30,
85+
Memory_Access_Control = 0x36,
86+
Pixel_Format_Set = 0x3A,
87+
Memory_Write_Continue = 0x3C,
88+
Write_Display_Brightness = 0x51,
89+
Frame_Rate_Control_Normal = 0xB1,
90+
Frame_Rate_Control_2 = 0xB2,
91+
Frame_Rate_Control_3 = 0xB3,
92+
Invert_On = 0xB4,
93+
Display_Function_Control = 0xB6,
94+
Entry_Mode_Set = 0xB7,
95+
Power_Control_1 = 0xC0,
96+
Power_Control_2 = 0xC1,
97+
Power_Control_3 = 0xC2,
98+
Power_Control_4 = 0xC3,
99+
Power_Control_5 = 0xC4,
100+
VCOM_Control_1 = 0xC5,
101+
VCOM_Control_2 = 0xC7,
102+
Power_Control_A = 0xCB,
103+
Power_Control_B = 0xCF,
104+
Positive_Gamma_Correction = 0xE0,
105+
Negative_Gamma_Correction = 0XE1,
106+
Driver_Timing_Control_A = 0xE8,
107+
Driver_Timing_Control_B = 0xEA,
108+
Power_On_Sequence = 0xED,
109+
Enable_3G = 0xF2,
110+
Pump_Ratio_Control = 0xF7,
111+
Power_Control_6 = 0xFC,
112+
};
113+
114+
[Flags]
115+
private enum St7735Orientation
116+
{
117+
MADCTL_MH = 0x04, // sets the Horizontal Refresh, 0=Left-Right and 1=Right-Left
118+
MADCTL_ML = 0x10, // sets the Vertical Refresh, 0=Top-Bottom and 1=Bottom-Top
119+
MADCTL_MV = 0x20, // sets the Row/Column Swap, 0=Normal and 1=Swapped
120+
MADCTL_MX = 0x40, // sets the Column Order, 0=Left-Right and 1=Right-Left
121+
MADCTL_MY = 0x80, // sets the Row Order, 0=Top-Bottom and 1=Bottom-Top
122+
123+
MADCTL_BGR = 0x08 // Blue-Green-Red pixel order
124+
};
125+
```
126+
127+
And build the driver like this:
128+
129+
```csharp
130+
// This is your SPI configuration
131+
var displaySpiConfig = new SpiConfiguration(
132+
1,
133+
ChipSelect,
134+
DataCommand,
135+
Reset,
136+
-1);
137+
138+
// Here we create the driver
139+
GraphicDriver graphicDriver = new GraphicDriver()
140+
{
141+
MemoryWrite = 0x2C,
142+
SetColumnAddress = 0x2A,
143+
SetRowAddress = 0x2B,
144+
InitializationSequence = new byte[]
145+
{
146+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.SOFTWARE_RESET,
147+
// Sleep for 50 ms
148+
(byte)GraphicDriverCommandType.Sleep, 5,
149+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.Sleep_Out,
150+
// Sleep for 500 ms
151+
(byte)GraphicDriverCommandType.Sleep, 50,
152+
(byte)GraphicDriverCommandType.Command, 4, (byte)St7735.Frame_Rate_Control_Normal, 0x01, 0x2C, 0x2D,
153+
(byte)GraphicDriverCommandType.Command, 4, (byte)St7735.Frame_Rate_Control_2, 0x01, 0x2C, 0x2D,
154+
(byte)GraphicDriverCommandType.Command, 7, (byte)St7735.Frame_Rate_Control_3, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D,
155+
(byte)GraphicDriverCommandType.Command, 2, (byte)St7735.Invert_On, 0x07,
156+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.Invertion_On,
157+
// 0x55 -> 16 bit
158+
(byte)GraphicDriverCommandType.Command, 2, (byte)St7735.Pixel_Format_Set, 0x55,
159+
(byte)GraphicDriverCommandType.Command, 4, (byte)St7735.Power_Control_1, 0xA2, 0x02, 0x84,
160+
(byte)GraphicDriverCommandType.Command, 2, (byte)St7735.Power_Control_2, 0xC5,
161+
(byte)GraphicDriverCommandType.Command, 3, (byte)St7735.Power_Control_3, 0x0A, 0x00,
162+
(byte)GraphicDriverCommandType.Command, 3, (byte)St7735.Power_Control_4, 0x8A, 0x2A,
163+
(byte)GraphicDriverCommandType.Command, 3, (byte)St7735.Power_Control_5, 0x8A, 0xEE,
164+
(byte)GraphicDriverCommandType.Command, 4, (byte)St7735.VCOM_Control_1, 0x0E, 0xFF, 0xFF,
165+
(byte)GraphicDriverCommandType.Command, 17, (byte)St7735.Positive_Gamma_Correction, 0x02, 0x1c, 0x7, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10,
166+
(byte)GraphicDriverCommandType.Command, 17, (byte)St7735.Negative_Gamma_Correction, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x1,
167+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.Sleep_Out,
168+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.Display_ON,
169+
// Sleep 100 ms
170+
(byte)GraphicDriverCommandType.Sleep, 10,
171+
(byte)GraphicDriverCommandType.Command, 1, (byte)St7735.NOP,
172+
// Sleep 20 ms
173+
(byte)GraphicDriverCommandType.Sleep, 2,
174+
},
175+
OrientationLandscape = new byte[]
176+
{
177+
(byte)GraphicDriverCommandType.Command, 2, (byte)St7735.Memory_Access_Control, (byte)(St7735Orientation.MADCTL_MY | St7735Orientation.MADCTL_MX | St7735Orientation.MADCTL_BGR),
178+
},
179+
PowerModeNormal = new byte[]
180+
{
181+
(byte)GraphicDriverCommandType.Command, 3, (byte)St7735.POWER_STATE, 0x00, 0x00,
182+
},
183+
PowerModeSleep = new byte[]
184+
{
185+
(byte)GraphicDriverCommandType.Command, 3, (byte)St7735.POWER_STATE, 0x00, 0x01,
186+
},
187+
DefaultOrientation = DisplayOrientation.Landscape,
188+
Brightness = (byte)St7735.Write_Display_Brightness,
189+
};
190+
191+
// And the screen configuration:
192+
var screenConfig = new ScreenConfiguration(
193+
26,
194+
1,
195+
80,
196+
160,
197+
graphicDriver);
198+
199+
// And finally initialize the driver and the screen
200+
var init = DisplayControl.Initialize(
201+
displaySpiConfig,
202+
screenConfig,
203+
1024);
204+
```
205+
206+
Note that the initialization commands are mandatory. The rest of the commands are not mandatory. Now, some may be needed for a good usage of your driver.
207+
208+
All commands are following the same rule:
209+
210+
- (byte)GraphicDriverCommandType.Command, N, n0, n1, nN-1
211+
- (byte)GraphicDriverCommandType.Sleep, T
212+
213+
Where N is the number of bytes to send as a command, meaning the first element n0 is always a command and then the bytes from n1 to nN-1.
214+
215+
It is as well possible to insert sleep time where T represent a set of 10 milliseconds. So to wait 50 milliseconds, T must be 5.
216+
217+
### Availability of drivers
218+
219+
Different drivers for different screens are available as nuget.
220+
221+
Prefer the native implementation when it's available. Use the generic one when you don't have the competencies to rebuild your own image or you want to adjust the native driver.
222+
223+
The generic driver is also a great way to test and implement new drivers. It does not require to rebuild an image every time you want to test something new instead, you just adjust your managed code.
224+
225+
### Generic display driver limitations
226+
227+
The main limitation is related to the way all those SPI drivers are working with a notion of commands and data sent after with the exact same behavior to flash a buffer. If your driver is not following this pattern, there are changes that this will not work.
228+
229+
There is the possibility to add more behaviors like flashing directly buffers or adjust the way things are working. Please open issues or provide a PR to improve all this.
230+
61231
## Feedback and documentation
62232

63233
For documentation, providing feedback, issues and finding out how to contribute please refer to the [Home repo](https://github.com/nanoframework/Home).

nanoFramework.Graphics/Primitive/DisplayControl.cs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,29 +10,6 @@
1010

1111
namespace nanoFramework.UI
1212
{
13-
/// <summary>
14-
/// Display orientation. No all display drivers support every orientation.
15-
/// </summary>
16-
public enum DisplayOrientation : int
17-
{
18-
/// <summary>
19-
/// Portrait
20-
/// </summary>
21-
PORTRAIT,
22-
/// <summary>
23-
/// Portrait 180
24-
/// </summary>
25-
PORTRAIT180,
26-
/// <summary>
27-
/// Landscape
28-
/// </summary>
29-
LANDSCAPE,
30-
/// <summary>
31-
/// Landscape 180
32-
/// </summary>
33-
LANDSCAPE180
34-
};
35-
3613
/// <summary>
3714
/// Display Control.
3815
/// </summary>

nanoFramework.Graphics/Primitive/DisplayInterfaceConfig.cs

Lines changed: 0 additions & 143 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// Portions Copyright (c) Microsoft Corporation. All rights reserved.
4+
// See LICENSE file in the project root for full license information.
5+
//
6+
7+
namespace nanoFramework.UI
8+
{
9+
/// <summary>
10+
/// Display orientation. No all display drivers support every orientation.
11+
/// </summary>
12+
public enum DisplayOrientation
13+
{
14+
/// <summary>
15+
/// Portrait.
16+
/// </summary>
17+
Portrait,
18+
19+
/// <summary>
20+
/// Portrait 180.
21+
/// </summary>
22+
Portrait180,
23+
24+
/// <summary>
25+
/// Landscape.
26+
/// </summary>
27+
Landscape,
28+
29+
/// <summary>
30+
/// Landscape 180.
31+
/// </summary>
32+
Landscape180
33+
};
34+
}

0 commit comments

Comments
 (0)