Skip to content

Commit ca385fc

Browse files
committed
added reusable MonchromeReader
1 parent 3011530 commit ca385fc

15 files changed

+363
-535
lines changed

Diff for: src/modm/driver/display/ili9341.hpp

+30-35
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ class Ili9341 : public Interface,
5353
using ReadCommand = ili9341_register::ReadCommand;
5454

5555
public:
56-
using colorType = color::Rgb565<true>;
56+
using C = color::Rgb565<true>;
5757

5858
template<typename... Args>
5959
Ili9341(Args &&...args)
6060
: Interface(std::forward<Args>(args)...),
61-
Display<colorType, Resolution<320, 240>, true>(color::html::White)
61+
Display<C, Resolution<320, 240>, true>(color::html::White)
6262
{ Reset::setOutput(modm::Gpio::High); }
6363

6464
~Ili9341(){};
@@ -105,41 +105,31 @@ class Ili9341 : public Interface,
105105
// Write from Pattern (compiletime poly)
106106
template<ColorPattern P>
107107
// FIXME Concept not accepted - but why?
108-
// requires std::derived_from<Pattern, modm::color::Pattern<colorType>>
108+
// requires std::derived_from<Pattern, modm::color::Pattern<C>>
109109
modm::ResumableResult<void>
110110
writePattern(Rectangle rectangle, P pattern);
111111

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

117-
// Write equal colored BufferInterface (runtime poly)
116+
// Write different colored BufferInterface
117+
template<Color C_>
118118
modm::ResumableResult<void>
119-
writeBuffer(const BufferInterface<colorType> *buffer, Point origin = {0, 0});
119+
writeBuffer(const BufferInterface<C_> *buffer, Point origin = {0, 0});
120120

121-
// Write different colored Buffer (compiletime poly)
122-
template<typename C_, typename R_, class Painter_>
123-
modm::ResumableResult<void>
124-
writeBuffer(const Buffer<C_, R_, Painter_> &buffer, Point origin = {0, 0});
125-
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;
139129

140130
// Clear whole screen with color
141131
modm::ResumableResult<void>
142-
clear(colorType color = html::Black);
132+
clear(C color = html::Black);
143133

144134
// ##################################################################
145135
// HACK Can't inherit modm::graphic::RemotePainter using RF
@@ -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:
@@ -181,10 +174,17 @@ class Ili9341 : public Interface,
181174
modm::ResumableResult<void>
182175
drawFast(Section section);
183176

184-
modm::ResumableResult<colorType>
177+
modm::ResumableResult<C>
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+
}
186+
187+
// OPTIMIZE make a final check, if the union/struct/union is great enough
188188
union {
189189
// Buffers for commands & configuration
190190
uint8_t buff_cmd8[15];
@@ -194,24 +194,19 @@ class Ili9341 : public Interface,
194194
// Parallel use in resumable function: don't overlap!
195195
struct
196196
{
197-
uint16_t buff_cmd_clipping[2];
198-
199-
// Primary Pixelbuffer
200-
colorType buffer[BC];
201-
size_t buffer_i;
197+
MonochromeReader mono_reader; // Helper to read monochrome data
202198

203-
size_t pixels_to_write, pixel_bulk;
199+
C buffer[BC]; // Bulk buffer
200+
size_t i; // Bulk buffer index
201+
Point scanner; // display index
204202

205-
// Keep track of current position in
206-
Point scanner;
207-
ScannerBufferBool bool_scanner;
203+
size_t pixels; // Pixels of whole transaction
204+
size_t pixels_bulk; // Pixels of current bulk
208205

209-
colorType temp_color;
206+
uint16_t buff_cmd_clipping[2];
207+
C temp_color; // Temporary storage for a color
210208
} p; // p for parallel
211209
};
212-
213-
// BUG Static variables for resumable functions RemotePainter
214-
Section section;
215210
};
216211

217212
} // namespace modm

Diff for: src/modm/driver/display/ili9341_impl.hpp

+86-79
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,109 @@ 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(p.buffer, 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<C> *buffer, Point origin) {
282277
RF_BEGIN();
283278

284-
this->clipping = this->getIntersection(Rectangle(origin, R_::asPoint()));
279+
this->layout = buffer->getLayout();
280+
281+
this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
285282
RF_CALL(updateClipping());
286283

287-
// FIXME take this->clipping into account
288-
RF_CALL(this->writeData(buffer.getPlainBuffer(), p.pixels_to_write * 2));
284+
// Add left offset
285+
if(origin.x < 0)
286+
this->layout.buffer += -origin.x * this->layout.size.y * 2;
287+
288+
// Check if we exceed the display vertically
289+
if (origin.y < 0 or origin.y + this->layout.size.y != this->clipping.bottomRight.y)
290+
{
291+
// Add top offset
292+
if(origin.y < 0)
293+
this->layout.buffer += -origin.y * 2;
294+
295+
// Can't transfer buffer continuously, send row by row
296+
p.pixels_bulk = this->clipping.getHeight();
297+
while(p.pixels) {
298+
RF_CALL(this->writeData((C*)(this->layout.buffer), p.pixels_bulk));
299+
this->layout.buffer += this->layout.size.y * 2;
300+
p.pixels -= p.pixels_bulk;
301+
}
302+
} else
303+
{
304+
// Transfer buffer continuously in one shot
305+
RF_CALL(this->writeData((C*)(this->layout.buffer), p.pixels));
306+
}
307+
289308
RF_END();
290309
}
291310

292-
// -- Write equal colored BufferInterface -----------------------------
311+
// -- Write different colored BufferInterface -----------------------------
293312
template<class Interface, class Reset, size_t BC>
313+
template<Color C_>
294314
modm::ResumableResult<void>
295315
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
296-
const BufferInterface<colorType> *buffer, Point origin) {
316+
const BufferInterface<C_> *buffer, Point origin) {
297317
RF_BEGIN();
298318

299-
this->clipping = this->getIntersection(Rectangle(origin, buffer->getResolution()));
319+
this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
300320
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();
306321

307322
RF_END();
308323
}
309324

310-
// -- Write monochrome Buffer -----------------------------
325+
// -- Write monochrome BufferInterface -------------------
311326
template<class Interface, class Reset, size_t BC>
312-
template<typename R_, class Painter_>
313327
modm::ResumableResult<void>
314328
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
315-
const Buffer<bool, R_, Painter_> &buffer, Point origin)
316-
{
329+
const BufferInterface<bool> *buffer, Point origin) {
317330
RF_BEGIN();
318331

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()));
332+
this->layout = buffer->getLayout();
333+
this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
324334
RF_CALL(updateClipping());
325335

326-
while (p.pixels_to_write)
336+
p.mono_reader = MonochromeReader(this->layout.buffer, this->layout.size.x, origin);
337+
p.scanner = this->clipping.topLeft;
338+
339+
while (p.pixels)
327340
{
328-
p.temp_color = html::Red;
329-
330341
// 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;
342+
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
343+
p.buffer[p.i] = p.mono_reader() ? color : C(html::Black);
344+
if (++p.scanner.y == this->clipping.bottomRight.y) {
345+
scannerNextRow();
346+
p.mono_reader.nextRow();
347+
}
337348
}
338-
339349
// Transfer
340-
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixel_bulk));
341-
p.pixels_to_write -= p.pixel_bulk;
350+
RF_CALL(this->writeData(p.buffer, p.i));
351+
p.pixels -= p.i;
342352
}
343-
RF_END();
344-
}
345353

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-
356354
RF_END();
357355
}
358356

@@ -363,20 +361,29 @@ modm::Ili9341<Interface, Reset, BC>::writeFlash(modm::accessor::Flash<uint8_t> d
363361
uint16_t width, uint16_t height, Point origin) {
364362
RF_BEGIN();
365363

366-
this->clipping = this->getIntersection(Rectangle(origin, Point(width, height)));
364+
this->clipping = this->getIntersection(Rectangle(origin, {width, height}));
367365
RF_CALL(updateClipping());
368366

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;
367+
// FIXME MonochromeReader must learn to handle modm::accessor::Flash<uint8_t>
368+
// p.mono_reader = MonochromeReader(data, width, origin);
369+
p.scanner = this->clipping.topLeft;
370+
371+
while (p.pixels)
372+
{
373+
// Convert next Bulk
374+
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
375+
// p.buffer[p.i] = p.mono_reader() ? color : C(html::Black);
376+
if (++p.scanner.y == this->clipping.bottomRight.y) {
377+
scannerNextRow();
378+
// p.mono_reader.nextRow();
379+
}
380+
}
381+
// Transfer
382+
RF_CALL(this->writeData(p.buffer, p.i));
383+
p.pixels -= p.i;
384+
}
378385

379-
RF_END();
386+
RF_END();
380387
}
381388

382389
// -- Draw primitive Shapes ------------------------------
@@ -421,21 +428,21 @@ modm::Ili9341<Interface, Reset, BC>::drawFast(Section section)
421428
// See https://github.com/modm-io/modm/issues/666
422429

423430
// 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);
431+
p.pixels_bulk = std::min<size_t>(BC, p.pixels);
432+
std::fill(p.buffer, p.buffer + p.pixels_bulk, color);
426433

427-
while (p.pixels_to_write)
434+
while (p.pixels)
428435
{
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);
436+
p.pixels -= p.pixels_bulk;
437+
RF_CALL(this->writeData(p.buffer, p.pixels_bulk));
438+
p.pixels_bulk = std::min<size_t>(BC, p.pixels);
432439
}
433440
RF_END();
434441
}
435442

436443
template<class Interface, class Reset, size_t BC>
437444
modm::ResumableResult<void>
438-
modm::Ili9341<Interface, Reset, BC>::clear(colorType color)
445+
modm::Ili9341<Interface, Reset, BC>::clear(C color)
439446
{
440447
// OPTIMIZE Make this impossible fast through use of DMA
441448
// See https://github.com/modm-io/modm/issues/666

0 commit comments

Comments
 (0)