Skip to content

Commit ca9176d

Browse files
committed
added reusable MonchromeReader
1 parent 3011530 commit ca9176d

14 files changed

+309
-499
lines changed

src/modm/driver/display/ili9341.hpp

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -109,30 +109,20 @@ class Ili9341 : public Interface,
109109
modm::ResumableResult<void>
110110
writePattern(Rectangle rectangle, P pattern);
111111

112-
// Write equal colored Buffer (compiletime poly)
113-
template<typename R_, class Painter_>
114-
modm::ResumableResult<void>
115-
writeBuffer(const Buffer<colorType, R_, Painter_> &buffer, Point origin = {0, 0});
116-
117-
// Write equal colored BufferInterface (runtime poly)
112+
// Write equal colored BufferInterface
118113
modm::ResumableResult<void>
119114
writeBuffer(const BufferInterface<colorType> *buffer, Point origin = {0, 0});
120115

121-
// Write different colored Buffer (compiletime poly)
122-
template<typename C_, typename R_, class Painter_>
116+
// Write different colored BufferInterface
117+
template<Color C_>
123118
modm::ResumableResult<void>
124-
writeBuffer(const Buffer<C_, R_, Painter_> &buffer, Point origin = {0, 0});
119+
writeBuffer(const BufferInterface<C_> *buffer, Point origin = {0, 0});
125120

126-
// Write monochrome Buffer (compiletime poly)
127-
template<typename R_, class Painter_>
128-
modm::ResumableResult<void>
129-
writeBuffer(const Buffer<bool, R_, Painter_> &buffer, Point origin = {0, 0});
130-
131-
// Write monochrome BufferInterface (runtime poly)
121+
// Write monochrome BufferInterface
132122
modm::ResumableResult<void>
133123
writeBuffer(const BufferInterface<bool> *buffer, Point origin = {0, 0});
134124

135-
// Write monochrome Flash (runtime poly)
125+
// Write monochrome Flash
136126
modm::ResumableResult<void>
137127
writeFlash(modm::accessor::Flash<uint8_t> data, uint16_t width, uint16_t height,
138128
Point origin = {0, 0}) final;
@@ -159,6 +149,9 @@ class Ili9341 : public Interface,
159149
protected:
160150
modm::ResumableResult<void>
161151
drawQuadPoints(Point center, Point point);
152+
private:
153+
// Static variables for resumable functions
154+
Section section;
162155
// ##################################################################
163156

164157
protected:
@@ -184,7 +177,12 @@ class Ili9341 : public Interface,
184177
modm::ResumableResult<colorType>
185178
getFast(Point point) const;
186179

180+
private:
187181
// Static variables for resumable functions
182+
void scannerNextRow() {
183+
p.scanner.x++;
184+
p.scanner.y = this->clipping.topLeft.y;
185+
}
188186
union {
189187
// Buffers for commands & configuration
190188
uint8_t buff_cmd8[15];
@@ -195,23 +193,18 @@ class Ili9341 : public Interface,
195193
struct
196194
{
197195
uint16_t buff_cmd_clipping[2];
196+
colorType buffer[BC]; // Primary Pixelbuffer
197+
size_t i; // Current Index in Primary Pixelbuffer
198+
Point scanner; // Current Index on Display
198199

199-
// Primary Pixelbuffer
200-
colorType buffer[BC];
201-
size_t buffer_i;
202-
203-
size_t pixels_to_write, pixel_bulk;
204-
205-
// Keep track of current position in
206-
Point scanner;
207-
ScannerBufferBool bool_scanner;
200+
size_t pixels; // Pixels of whole transaction
201+
size_t pixels_bulk; // Pixels of current bulk
202+
203+
MonochromeReader mono_reader; // Helper to read monochrome data
208204

209-
colorType temp_color;
205+
colorType temp_color; // Temporary storage for a color
210206
} p; // p for parallel
211207
};
212-
213-
// BUG Static variables for resumable functions RemotePainter
214-
Section section;
215208
};
216209

217210
} // namespace modm

src/modm/driver/display/ili9341_impl.hpp

Lines changed: 71 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ modm::Ili9341<Interface, Reset, BC>::updateClipping()
231231
RF_CALL(this->writeCommand(Command::ColumnAddressSet, (uint8_t *)(p.buff_cmd_clipping), 4));
232232

233233
RF_CALL(this->writeCommand(Command::MemoryWrite));
234-
p.pixels_to_write = this->clipping.getPixels();
234+
p.pixels = this->clipping.getPixels();
235235

236236
RF_END();
237237
}
@@ -248,111 +248,95 @@ modm::Ili9341<Interface, Reset, BC>::writePattern(Rectangle rectangle, P pattern
248248

249249
p.scanner = this->clipping.topLeft;
250250

251-
while (p.pixels_to_write)
251+
while (p.pixels)
252252
{
253253
// Generate next bulk
254-
for(p.buffer_i = 0; p.buffer_i < std::min<uint32_t>(p.pixels_to_write, BC); p.buffer_i++) {
254+
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
255255
// OPTIMIZE inefficient, cause pattern recalculates color for each pixel
256-
// Let's investigate a solution
257-
p.buffer[p.buffer_i] = pattern(p.scanner);
258-
259-
// Update scanner
256+
// even when it could already know, under withc conditions the return-value changes!
257+
// Need some kind of caching!?
258+
p.buffer[p.i] = pattern(p.scanner);
259+
260260
if (++p.scanner.y == this->clipping.bottomRight.y) {
261-
p.scanner.x++;
262-
p.scanner.y = this->clipping.topLeft.y;
261+
scannerNextRow();
263262
}
264263
}
265-
266264
// Transfer
267-
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.buffer_i));
268-
269-
p.pixels_to_write-= p.buffer_i;
265+
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.i));
266+
p.pixels-= p.i;
270267
}
271268

272269
RF_END();
273270
}
274271

275-
// -- Write equal colored Buffer ----------------------------------
272+
// -- Write equal colored BufferInterface -----------------------------
276273
template<class Interface, class Reset, size_t BC>
277-
template<typename R_, class Painter_>
278274
modm::ResumableResult<void>
279275
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
280-
const Buffer<colorType, R_, Painter_> &buffer, Point origin)
281-
{
276+
const BufferInterface<colorType> *buffer, Point origin) {
282277
RF_BEGIN();
283278

284-
this->clipping = this->getIntersection(Rectangle(origin, R_::asPoint()));
279+
this->clipping = this->getIntersection(Rectangle(origin, buffer->getSize()));
285280
RF_CALL(updateClipping());
286281

287-
// FIXME take this->clipping into account
288-
RF_CALL(this->writeData(buffer.getPlainBuffer(), p.pixels_to_write * 2));
282+
if (yInCanvas(origin.y) and yInCanvas(origin.y + buffer->getSize().y))
283+
{
284+
p.pixels = this->clipping.getPixels();
285+
// Calculate left buffer-offset
286+
p.pixels_bulk = origin.x < 0 ? -origin.x * this->clipping.getHeight() : 0;
287+
RF_CALL(this->writeData(buffer->getPlainBuffer() + p.pixels_bulk, 2 * p.pixels));
288+
} else
289+
{
290+
// IMPLEMENT Can't transfer buffer continuously
291+
// What's the best strategy? copy to p.buffer (using DMA2D if available) or send row by row?
292+
RF_RETURN();
293+
}
294+
289295
RF_END();
290296
}
291297

292-
// -- Write equal colored BufferInterface -----------------------------
298+
// -- Write different colored BufferInterface -----------------------------
293299
template<class Interface, class Reset, size_t BC>
300+
template<Color C_>
294301
modm::ResumableResult<void>
295302
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
296-
const BufferInterface<colorType> *buffer, Point origin) {
303+
const BufferInterface<C_> *buffer, Point origin) {
297304
RF_BEGIN();
298305

299-
this->clipping = this->getIntersection(Rectangle(origin, buffer->getResolution()));
306+
this->clipping = this->getIntersection(Rectangle(origin, buffer->getSize()));
300307
RF_CALL(updateClipping());
301-
302-
// Reload scanner
303-
p.bool_scanner = ScannerBufferBool(origin);
304-
p.bool_scanner.print_top();
305-
p.bool_scanner.print_state();
306308

307309
RF_END();
308310
}
309311

310-
// -- Write monochrome Buffer -----------------------------
312+
// -- Write monochrome BufferInterface -------------------
311313
template<class Interface, class Reset, size_t BC>
312-
template<typename R_, class Painter_>
313314
modm::ResumableResult<void>
314315
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
315-
const Buffer<bool, R_, Painter_> &buffer, Point origin)
316-
{
316+
const BufferInterface<bool> *buffer, Point origin) {
317317
RF_BEGIN();
318318

319-
// Reload scanner
320-
p.bool_scanner = ScannerBufferBool(buffer.getPlainBuffer(), origin);
321-
p.bool_scanner.print_top();
322-
323-
this->clipping = this->getIntersection(Rectangle(origin, R_::asPoint()));
319+
this->clipping = this->getIntersection(Rectangle(origin, buffer->getSize()));
324320
RF_CALL(updateClipping());
325321

326-
while (p.pixels_to_write)
322+
p.mono_reader = MonochromeReader(buffer->getPlainBuffer(), buffer->getSize().x, origin);
323+
p.scanner = this->clipping.topLeft;
324+
325+
while (p.pixels)
327326
{
328-
p.temp_color = html::Red;
329-
330327
// Convert next Bulk
331-
p.pixel_bulk = std::min<size_t>(p.pixels_to_write, BC);
332-
for(p.buffer_i = 0; p.buffer_i < p.pixel_bulk; p.buffer_i++) {
333-
// p.bool_scanner.print_state();
334-
// p.buffer[p.buffer_i] = p.bool_scanner() ? color : colorType(html::Black);
335-
p.temp_color.color++;
336-
p.buffer[p.buffer_i] = p.temp_color;
328+
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
329+
p.buffer[p.i] = p.mono_reader() ? color : colorType(html::Black);
330+
if (++p.scanner.y == this->clipping.bottomRight.y) {
331+
scannerNextRow();
332+
p.mono_reader.nextRow();
333+
}
337334
}
338-
339335
// Transfer
340-
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixel_bulk));
341-
p.pixels_to_write -= p.pixel_bulk;
336+
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.i));
337+
p.pixels -= p.i;
342338
}
343-
RF_END();
344-
}
345339

346-
// -- Write monochrome BufferInterface -------------------
347-
template<class Interface, class Reset, size_t BC>
348-
modm::ResumableResult<void>
349-
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
350-
const BufferInterface<bool> *buffer, Point origin) {
351-
RF_BEGIN();
352-
353-
MODM_LOG_DEBUG << __FUNCTION__ << modm::endl;
354-
MODM_LOG_DEBUG << "origin: " << origin << ", resolution: " << buffer->getResolution() << modm::endl;
355-
356340
RF_END();
357341
}
358342

@@ -363,20 +347,29 @@ modm::Ili9341<Interface, Reset, BC>::writeFlash(modm::accessor::Flash<uint8_t> d
363347
uint16_t width, uint16_t height, Point origin) {
364348
RF_BEGIN();
365349

366-
this->clipping = this->getIntersection(Rectangle(origin, Point(width, height)));
350+
this->clipping = this->getIntersection(Rectangle(origin, {width, height}));
367351
RF_CALL(updateClipping());
368352

369-
// Reload scanner
370-
// p.bool_scanner = ScannerBufferBool(data, origin);
371-
// p.bool_scanner.print_top();
372-
// p.bool_scanner.print_state();
373-
374-
(void)data;
375-
(void)width;
376-
(void)height;
377-
(void)origin;
353+
// FIXME MonochromeReader must learn to handle modm::accessor::Flash<uint8_t>
354+
// p.mono_reader = MonochromeReader(data, width, origin);
355+
p.scanner = this->clipping.topLeft;
356+
357+
while (p.pixels)
358+
{
359+
// Convert next Bulk
360+
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
361+
// p.buffer[p.i] = p.mono_reader() ? color : colorType(html::Black);
362+
if (++p.scanner.y == this->clipping.bottomRight.y) {
363+
scannerNextRow();
364+
// p.mono_reader.nextRow();
365+
}
366+
}
367+
// Transfer
368+
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.i));
369+
p.pixels -= p.i;
370+
}
378371

379-
RF_END();
372+
RF_END();
380373
}
381374

382375
// -- Draw primitive Shapes ------------------------------
@@ -421,14 +414,14 @@ modm::Ili9341<Interface, Reset, BC>::drawFast(Section section)
421414
// See https://github.com/modm-io/modm/issues/666
422415

423416
// Without DMA, at least this could be parallelised to updateClipping(..) above
424-
p.pixel_bulk = std::min<size_t>(BC, p.pixels_to_write);
425-
std::fill(p.buffer, p.buffer + p.pixel_bulk, color);
417+
p.pixels_bulk = std::min<size_t>(BC, p.pixels);
418+
std::fill(p.buffer, p.buffer + p.pixels_bulk, color);
426419

427-
while (p.pixels_to_write)
420+
while (p.pixels)
428421
{
429-
p.pixels_to_write -= p.pixel_bulk;
430-
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixel_bulk));
431-
p.pixel_bulk = std::min<size_t>(BC, p.pixels_to_write);
422+
p.pixels -= p.pixels_bulk;
423+
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixels_bulk));
424+
p.pixels_bulk = std::min<size_t>(BC, p.pixels);
432425
}
433426
RF_END();
434427
}

src/modm/driver/display/sh1106.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,11 @@ class Sh1106 : public Ssd1306<I2cMaster, H>
3737

3838
Sh1106(uint8_t address = 0x3C) : Ssd1306<I2cMaster, H>(address) {}
3939

40-
// Write monochrome Buffer via BufferInterface
40+
// Write monochrome BufferInterface
4141
// Caution: origin.y rounds to multiples of 8
4242
modm::ResumableResult<bool>
4343
writeBuffer(const BufferInterface<colorType> *buffer, Point origin = {0, 0});
4444

45-
// Write monochrome Buffer
46-
// Caution: origin.y rounds to multiples of 8
47-
template<typename R_, class Painter_>
48-
modm::ResumableResult<bool>
49-
writeBuffer(const Buffer<colorType, R_, Painter_> &buffer, Point origin = {0, 0});
50-
5145
protected:
5246
modm::ResumableResult<bool>
5347
initializeMemoryMode() override;

src/modm/driver/display/sh1106_impl.hpp

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ modm::ResumableResult<bool>
4949
modm::Sh1106<I2cMaster, H>::writeBuffer(const BufferInterface<colorType> *buffer, Point origin) {
5050
RF_BEGIN();
5151

52-
this->clipping = Rectangle(origin, buffer->getResolution());
52+
this->clipping = Rectangle(origin, buffer->getSize());
5353

5454
if (this->pointInCanvas(this->clipping.bottomRight - Point(1, 1)))
5555
{
@@ -63,7 +63,7 @@ modm::Sh1106<I2cMaster, H>::writeBuffer(const BufferInterface<colorType> *buffer
6363
this->commandBuffer[2] = ssd1306::AdressingCommands::PageStartAddress | yd;
6464
this->transaction_success &= RF_CALL(this->writeCommands(3));
6565

66-
RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(buffer.getPlainBuffer() + (buffer->getResolution().x * yb++), buffer->getResolution()));
66+
RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(buffer->getPlainBuffer() + (this->clipping.getWidth() * yb++), this->clipping.getWidth()));
6767
RF_WAIT_UNTIL(this->startTransaction());
6868
RF_WAIT_WHILE(this->isTransactionRunning());
6969
this->transaction_success &= this->wasTransactionSuccessful();
@@ -73,37 +73,4 @@ modm::Sh1106<I2cMaster, H>::writeBuffer(const BufferInterface<colorType> *buffer
7373
this->transaction_success = false;
7474
}
7575
RF_END_RETURN(this->transaction_success);
76-
}
77-
78-
template<class I2cMaster, uint16_t H>
79-
template<typename R_, class Painter_>
80-
modm::ResumableResult<bool>
81-
modm::Sh1106<I2cMaster, H>::writeBuffer(const Buffer<colorType, R_, Painter_> &buffer, Point origin)
82-
{
83-
RF_BEGIN();
84-
85-
this->clipping = Rectangle(origin, R_::asPoint());
86-
87-
if (this->pointInCanvas(this->clipping.bottomRight - Point(1, 1)))
88-
{
89-
RF_CALL(updateClipping());
90-
91-
this->transaction_success = true;
92-
yb = 0;
93-
94-
for (yd = yd_start; yd <= yd_end; yd++)
95-
{
96-
this->commandBuffer[2] = ssd1306::AdressingCommands::PageStartAddress | yd;
97-
this->transaction_success &= RF_CALL(this->writeCommands(3));
98-
99-
RF_WAIT_UNTIL(this->transaction.configureDisplayWrite(
100-
buffer.getPlainBuffer() + (R_::W * yb++), R_::W));
101-
RF_WAIT_UNTIL(this->startTransaction());
102-
RF_WAIT_WHILE(this->isTransactionRunning());
103-
this->transaction_success &= this->wasTransactionSuccessful();
104-
};
105-
} else {
106-
this->transaction_success = false;
107-
}
108-
RF_END_RETURN(this->transaction_success);
10976
}

0 commit comments

Comments
 (0)