Skip to content

Commit f5ca4b4

Browse files
committed
generalize the waveform LUT to drivers
1 parent 9010a02 commit f5ca4b4

4 files changed

Lines changed: 165 additions & 99 deletions

File tree

lib/util/epd/driver/driver.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
1+
import 'waveform.dart';
2+
13
abstract class Driver {
24
String get driverName;
35
List<int> get transmissionLines;
46
int get refresh;
7+
int get vcomLut;
8+
int get wwLut;
9+
int get bwLut;
10+
int get wbLut;
11+
int get bbLut;
12+
int get panelSetting;
13+
int get pllControl;
14+
WaveformList get waveforms;
515
}

lib/util/epd/driver/uc8253.dart

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,111 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:magic_epaper_app/util/epd/driver/waveform.dart';
13
import 'driver.dart';
24

5+
const int GND = 0;
6+
const int VSH = 0x40;
7+
const int VSL = 0x80;
8+
const int VDHR = 0x60;
9+
10+
class QuickLut extends Waveform {
11+
@override
12+
String get desc => "Quick waveform for R_sense = 4R7 and PLL = 10Hz";
13+
@override
14+
int get pll => 0x01; // 10Hz
15+
@override
16+
List<Lut> get luts => [
17+
Lut(
18+
cmd: 0x20,
19+
data: Uint8List.fromList([
20+
// lut_vcom_quick
21+
0x01, 0x00, 10, 0x00, 0x00, 0x01, 0x00,
22+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27+
28+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30+
])),
31+
Lut(
32+
cmd: 0x21,
33+
data: Uint8List.fromList([
34+
// lut_ww_quick
35+
0x01, VSL | 10, 0x00, 0x00, 0x00, 0x01, 0x00,
36+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41+
])),
42+
Lut(
43+
cmd: 0x22,
44+
data: Uint8List.fromList([
45+
// lut_r_quick
46+
0x01, VSL | 10, 0x00, 0x00, 0x00, 0x01, 0x00,
47+
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
48+
0x01, VSH | 10, 5, 0x00, 0x00, 0x02, 0x00,
49+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52+
53+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55+
])),
56+
Lut(
57+
cmd: 0x23,
58+
data: Uint8List.fromList([
59+
// lut_w_quick
60+
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
61+
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
62+
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
63+
0x00, VSH | 2, 0x00, 0x00, 0x00, 0x01, 0x00,
64+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66+
67+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69+
])),
70+
Lut(
71+
cmd: 0x24,
72+
data: Uint8List.fromList([
73+
// lut_b_quick
74+
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
75+
0x01, VSH | 12, 0x00, 0x00, 0x00, 0x01, 0x00,
76+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80+
81+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83+
])),
84+
];
85+
}
86+
387
// UC8253 commands/registers,
488
// define in the epaper display controller (UC8253) reference manual
589
class Uc8253 extends Driver {
690
@override
791
int get refresh => 0x12;
892
@override
93+
int get vcomLut => 0x20;
94+
@override
95+
int get wwLut => 0x21;
96+
@override
97+
int get bwLut => 0x22;
98+
@override
99+
int get wbLut => 0x23;
100+
@override
101+
int get bbLut => 0x24;
102+
@override
103+
int get panelSetting => 0x00;
104+
@override
105+
int get pllControl => 0x30;
106+
@override
107+
WaveformList waveforms = [QuickLut()];
108+
@override
9109
get driverName => 'UC8253';
10110
@override
11111
List<int> get transmissionLines => [0x10, 0x13];

lib/util/epd/driver/waveform.dart

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import 'dart:typed_data';
2+
3+
// Single lut for a specific color
4+
class Lut {
5+
int cmd;
6+
Uint8List data;
7+
8+
Lut({required this.cmd, required this.data});
9+
}
10+
11+
// A set of luts for a display
12+
abstract class Waveform {
13+
String get desc;
14+
int get pll;
15+
List<Lut> get luts;
16+
}
17+
18+
// A list of waveform a display may have and to be selected depends on the
19+
// current sensing resistor and the PLL setting
20+
typedef WaveformList = List<Waveform>;

lib/util/protocol.dart

Lines changed: 35 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:magic_epaper_app/util/epd/epd.dart';
1010
import 'package:app_settings/app_settings.dart';
1111
import 'package:magic_epaper_app/util/magic_epaper_firmware.dart';
1212
import 'package:magic_epaper_app/util/nfc_settings_launcher.dart';
13+
import 'epd/driver/waveform.dart';
1314

1415
class Protocol {
1516
final fw = MagicEpaperFirmware();
@@ -45,14 +46,15 @@ class Protocol {
4546
Future<Uint8List> enableEnergyHarvesting(Uint8List tagId) async {
4647
return await _writeDynCfg(tagId, 0x02, 0x01);
4748
}
48-
49+
4950
// `pt_scan = true` means don't touch the outside pixels while refreshing
50-
Future<Uint8List> _setPartialWindow(Uint8List tagId, int xsbank, int xebank, int ys, int ye, bool pt_scan) async {
51+
Future<Uint8List> _setPartialWindow(Uint8List tagId, int xsbank, int xebank,
52+
int ys, int ye, bool pt_scan) async {
5153
// FIXME: move these constants to a specific controller
5254
if (xsbank > 0x1d) throw "Horizontal start channel bank must be <= 0x1D";
5355
if (xebank > 0x1d) throw "Horizontal end channel bank must be <= 0x1D";
5456
if (xsbank >= xebank) throw "Start channel must be < End channel bank";
55-
57+
5658
if (ys > 0x1df) throw "Horizontal start channel bank must be <= 0x1DF";
5759
if (ye > 0x1df) throw "Horizontal end channel bank must be <= 0x1DF";
5860
if (ys >= ye) throw "Start channel must be < End channel bank";
@@ -65,117 +67,49 @@ class Protocol {
6567
int VRED70 = ye & 0xff;
6668

6769
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, 0x90]));
68-
return await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, HRST73, HRED73, VRST8, VRST70, VRED8, VRED70, pt_scan ? 1 : 0]));
70+
return await _writeMsg(
71+
tagId,
72+
Uint8List.fromList([
73+
fw.epdSend,
74+
HRST73,
75+
HRED73,
76+
VRST8,
77+
VRST70,
78+
VRED8,
79+
VRED70,
80+
pt_scan ? 1 : 0
81+
]));
6982
}
7083

7184
void _partialIn(Uint8List tagId) async {
85+
// FIXME:
7286
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, 0x91]));
7387
}
7488

7589
void _partialOut(Uint8List tagId) async {
90+
// FIXME:
7691
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, 0x92]));
7792
}
7893

79-
80-
static const int GND = 0;
81-
static const int VSH = 0x40;
82-
static const int VSL = 0x80;
83-
static const int VDHR = 0x60;
84-
85-
static const int VCOM_LUT = 0x20;
86-
static const int W2W_LUT = 0x21;
87-
static const int B2W_LUT = 0x22;
88-
static const int W2B_LUT = 0x23;
89-
static const int B2B_LUT = 0x24;
90-
91-
static const int PANEL_SETTING = 0x00;
92-
static const int PLL_CONTROL = 0x30;
93-
94-
Uint8List lut_vcom_quick = Uint8List.fromList([
95-
0x01, 0x00, 10, 0x00, 0x00, 0x01, 0x00,
96-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
97-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101-
102-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104-
]);
105-
106-
// white gates go white with VSL
107-
Uint8List lut_ww_quick = Uint8List.fromList([
108-
0x01, VSL|10, 0x00, 0x00, 0x00, 0x01, 0x00,
109-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114-
]);
115-
116-
// red gates go white with VSL, go red with VSH
117-
Uint8List lut_r_quick = Uint8List.fromList([
118-
0x01, VSL|10, 0x00, 0x00, 0x00, 0x01, 0x00,
119-
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
120-
0x01, VSH|10, 5, 0x00, 0x00, 0x02, 0x00,
121-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124-
125-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127-
]);
128-
129-
// V*H will make white gates as black/red
130-
Uint8List lut_w_quick = Uint8List.fromList([
131-
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
132-
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
133-
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
134-
0x00, VSH|2, 0x00, 0x00, 0x00, 0x01, 0x00,
135-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137-
138-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140-
]);
141-
142-
// black gates go black/red with VSH
143-
Uint8List lut_b_quick = Uint8List.fromList([
144-
0x01, 10, 0x00, 0x00, 0x00, 0x01, 0x00,
145-
0x01, VSH|12, 0x00, 0x00, 0x00, 0x01, 0x00,
146-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150-
151-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153-
]);
154-
155-
Future<void> _setlut(Uint8List tagId) async {
156-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, PLL_CONTROL]));
94+
Future<void> _setlut(Uint8List tagId, Waveform waveform) async {
95+
await _writeMsg(
96+
tagId, Uint8List.fromList([fw.epdCmd, epd.controller.pllControl]));
15797
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, 0x01])); // 10hz
15898

159-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, VCOM_LUT]));
160-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut_vcom_quick]));
161-
162-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, W2W_LUT]));
163-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut_ww_quick]));
164-
165-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, B2W_LUT]));
166-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut_r_quick]));
167-
168-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, W2B_LUT]));
169-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut_w_quick]));
170-
171-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, B2B_LUT]));
172-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut_b_quick]));
99+
for (var lut in waveform.luts) {
100+
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, lut.cmd]));
101+
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, ...lut.data]));
102+
}
173103
}
174104

175105
Future<void> _panelSetting(Uint8List tagId) async {
176-
await _writeMsg(tagId, Uint8List.fromList([fw.epdCmd, PANEL_SETTING]));
106+
await _writeMsg(
107+
tagId, Uint8List.fromList([fw.epdCmd, epd.controller.panelSetting]));
177108
// await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, 0xCF, 0x8D])); // 480x240, built-in LUTs
178-
await _writeMsg(tagId, Uint8List.fromList([fw.epdSend, 0xEF, 0x8D])); // 480x240, LUTs from register
109+
await _writeMsg(
110+
tagId,
111+
Uint8List.fromList(
112+
[fw.epdSend, 0xEF, 0x8D])); // 480x240, LUTs from register
179113
}
180114

181115
Future<void> _sleep() async {
@@ -261,8 +195,10 @@ class Protocol {
261195
const Duration(seconds: 2)); // waiting for the power supply stable
262196

263197
// await _setPartialWindow(id, 0, epd.width ~/ 8 - 1, 0, epd.height - 1, true);
198+
199+
// FIXME: take input from the UI to enable the waveform. The built-in waveform should be used by default
264200
await _panelSetting(id);
265-
await _setlut(id);
201+
await _setlut(id, epd.controller.waveforms[0]);
266202

267203
final epdColors = epd.extractEpaperColorFrames(image);
268204
final transmissionLines = epd.controller.transmissionLines.iterator;

0 commit comments

Comments
 (0)