Skip to content

Commit 2ddd4dc

Browse files
authored
fix: move the display's initial code to the app (#78)
* feat: waveform luts * fix: move the display's initial code to the app Fixes #76
1 parent b9983ad commit 2ddd4dc

4 files changed

Lines changed: 185 additions & 22 deletions

File tree

lib/util/epd/driver/driver.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
import 'waveform.dart';
2+
import 'package:magic_epaper_app/util/protocol.dart';
3+
14
abstract class Driver {
25
String get driverName;
36
List<int> get transmissionLines;
47
int get refresh;
8+
int get vcomLut;
9+
int get wwLut;
10+
int get bwLut;
11+
int get wbLut;
12+
int get bbLut;
13+
int get panelSetting;
14+
int get pllControl;
15+
WaveformList get waveforms;
16+
Future<void> setlut(Protocol p, Waveform waveform);
17+
Future<void> init(Protocol p);
518
}

lib/util/epd/driver/uc8253.dart

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,142 @@
1+
import 'package:flutter/foundation.dart';
2+
import 'package:magic_epaper_app/util/epd/driver/waveform.dart';
3+
import 'package:magic_epaper_app/util/protocol.dart';
14
import 'driver.dart';
25

6+
class QuickLut extends Waveform {
7+
static const int GND = 0;
8+
static const int VSH = 0x40;
9+
static const int VSL = 0x80;
10+
static const int VDHR = 0x60;
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];
112+
113+
@override
114+
Future<void> setlut(Protocol p, Waveform waveform) async {
115+
await p.writeMsg(
116+
Uint8List.fromList([p.fw.epdCmd, p.epd.controller.pllControl]));
117+
await p.writeMsg(Uint8List.fromList([p.fw.epdSend, waveform.pll])); // 10hz
118+
119+
for (var lut in waveform.luts) {
120+
await p.writeMsg(Uint8List.fromList([p.fw.epdCmd, lut.cmd]));
121+
await p.writeMsg(Uint8List.fromList([p.fw.epdSend, ...lut.data]));
122+
}
123+
}
124+
125+
@override
126+
Future<void> init(Protocol p) async {
127+
// power on
128+
// FIXME: this command require polling the busy state but currently there is no way to do this in the app
129+
await p.writeMsg(Uint8List.fromList([p.fw.epdCmd, 0x04]));
130+
131+
// VCOM_AND_DATA_INTERVAL_SETTING
132+
await p.writeMsg(Uint8List.fromList([p.fw.epdCmd, 0x50]));
133+
await p.writeMsg(Uint8List.fromList([p.fw.epdSend, 0xff, 0x0f]));
134+
135+
await p.writeMsg(Uint8List.fromList([p.fw.epdCmd, panelSetting]));
136+
// 480x240, built-in LUTs
137+
await p.writeMsg(Uint8List.fromList([p.fw.epdSend, 0xCF, 0x8D]));
138+
// 480x240, LUTs from register
139+
// await p.writeMsg(Uint8List.fromList([p.fw.epdSend, 0xEF, 0x8D]));
140+
// await setlut(p, waveforms[0]);
141+
}
12142
}

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: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,46 +15,46 @@ class Protocol {
1515
final fw = MagicEpaperFirmware();
1616
final Epd epd;
1717
final timeout = const Duration(seconds: 5);
18+
late Uint8List tagId;
1819

1920
Protocol({required this.epd});
2021

21-
Future<Uint8List> _transceive(nfcvCmd, Uint8List tagId, Uint8List msg) async {
22+
Future<Uint8List> _transceive(nfcvCmd, Uint8List msg) async {
2223
final raw = fw.tagChip.buildMessage(nfcvCmd, tagId, msg);
2324
return await FlutterNfcKit.transceive(raw, timeout: timeout);
2425
}
2526

26-
Future<Uint8List> _writeMsg(Uint8List tagId, Uint8List msg) async {
27-
return await _transceive(fw.tagChip.writeMsgCmd, tagId, msg);
27+
Future<Uint8List> writeMsg(Uint8List msg) async {
28+
return await _transceive(fw.tagChip.writeMsgCmd, msg);
2829
}
2930

30-
Future<Uint8List> _readDynCfg(Uint8List tagId, int address) async {
31+
Future<Uint8List> _readDynCfg(int address) async {
3132
final raw = fw.tagChip.buildReadDynCfgCmd(tagId, address);
3233
return await FlutterNfcKit.transceive(raw, timeout: timeout);
3334
}
3435

35-
Future<Uint8List> _writeDynCfg(
36-
Uint8List tagId, int address, int value) async {
36+
Future<Uint8List> _writeDynCfg(int address, int value) async {
3737
final raw = fw.tagChip.buildWriteDynCfgCmd(tagId, address, value);
3838
return await FlutterNfcKit.transceive(raw, timeout: timeout);
3939
}
4040

41-
Future<bool> hasI2cGatheredMsg(Uint8List tagId) async {
42-
return ((await _readDynCfg(tagId, 0x0d)).elementAt(1) & 0x04) != 0x04;
41+
Future<bool> hasI2cGatheredMsg() async {
42+
return ((await _readDynCfg(0x0d)).elementAt(1) & 0x04) != 0x04;
4343
}
4444

45-
Future<Uint8List> enableEnergyHarvesting(Uint8List tagId) async {
46-
return await _writeDynCfg(tagId, 0x02, 0x01);
45+
Future<Uint8List> enableEnergyHarvesting() async {
46+
return await _writeDynCfg(0x02, 0x01);
4747
}
4848

4949
Future<void> _sleep() async {
5050
await Future.delayed(const Duration(milliseconds: 20));
5151
}
5252

53-
Future<void> wait4msgGathered(Uint8List tagId) async {
53+
Future<void> wait4msgGathered() async {
5454
var attempt = 4;
5555
while (attempt > 0) {
5656
try {
57-
if (await hasI2cGatheredMsg(tagId)) {
57+
if (await hasI2cGatheredMsg()) {
5858
return; // Exit successfully if message is gathered
5959
}
6060
} catch (e) {
@@ -70,16 +70,16 @@ class Protocol {
7070

7171
Future<void> writeFrame(Uint8List id, Uint8List frame, int cmd) async {
7272
final chunks = _split(data: frame);
73-
await _writeMsg(
74-
id, Uint8List.fromList([fw.epdCmd, cmd])); // enter transmission 1
73+
await writeMsg(
74+
Uint8List.fromList([fw.epdCmd, cmd])); // enter transmission 1
7575
await _sleep();
7676
for (int i = 0; i < chunks.length; i++) {
7777
Uint8List chunk = chunks[i];
7878
debugPrint(
7979
"Writing chunk ${i + 1}/${chunks.length} len ${chunk.lengthInBytes}: ${chunk.map((e) => e.toRadixString(16)).toList()}");
8080

81-
await _writeMsg(id, chunk);
82-
await wait4msgGathered(id);
81+
await writeMsg(chunk);
82+
await wait4msgGathered();
8383
}
8484
debugPrint("Transferred successfully.");
8585
}
@@ -119,24 +119,24 @@ class Protocol {
119119
final tag = await FlutterNfcKit.poll(timeout: timeout);
120120
debugPrint("Got a tag!");
121121

122-
var id = Uint8List.fromList(hex.decode(tag.id));
122+
tagId = Uint8List.fromList(hex.decode(tag.id));
123123
if (tag.type != NFCTagType.iso15693) {
124124
throw "Not a Magic Epaper Hardware";
125125
}
126126

127-
await enableEnergyHarvesting(id);
127+
await enableEnergyHarvesting();
128128
await Future.delayed(
129129
const Duration(seconds: 2)); // waiting for the power supply stable
130130

131+
await epd.controller.init(this);
132+
131133
final epdColors = epd.extractEpaperColorFrames(image);
132134
final transmissionLines = epd.controller.transmissionLines.iterator;
133135
for (final c in epdColors) {
134136
transmissionLines.moveNext();
135-
await writeFrame(id, c, transmissionLines.current);
137+
await writeFrame(tagId, c, transmissionLines.current);
136138
}
137139

138-
await _writeMsg(
139-
id, Uint8List.fromList([fw.epdCmd, epd.controller.refresh]));
140-
await FlutterNfcKit.finish();
140+
await writeMsg(Uint8List.fromList([fw.epdCmd, epd.controller.refresh]));
141141
}
142142
}

0 commit comments

Comments
 (0)