Skip to content

Commit

Permalink
added reusable MonchromeReader
Browse files Browse the repository at this point in the history
  • Loading branch information
TomSaw committed Aug 4, 2021
1 parent 3011530 commit ca385fc
Show file tree
Hide file tree
Showing 15 changed files with 363 additions and 535 deletions.
65 changes: 30 additions & 35 deletions src/modm/driver/display/ili9341.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ class Ili9341 : public Interface,
using ReadCommand = ili9341_register::ReadCommand;

public:
using colorType = color::Rgb565<true>;
using C = color::Rgb565<true>;

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

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

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

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

// Write different colored Buffer (compiletime poly)
template<typename C_, typename R_, class Painter_>
modm::ResumableResult<void>
writeBuffer(const Buffer<C_, R_, Painter_> &buffer, Point origin = {0, 0});

// Write monochrome Buffer (compiletime poly)
template<typename R_, class Painter_>
modm::ResumableResult<void>
writeBuffer(const Buffer<bool, R_, Painter_> &buffer, Point origin = {0, 0});

// Write monochrome BufferInterface (runtime poly)
// Write monochrome BufferInterface
modm::ResumableResult<void>
writeBuffer(const BufferInterface<bool> *buffer, Point origin = {0, 0});

// Write monochrome Flash (runtime poly)
// Write monochrome Flash
modm::ResumableResult<void>
writeFlash(modm::accessor::Flash<uint8_t> data, uint16_t width, uint16_t height,
Point origin = {0, 0}) final;

// Clear whole screen with color
modm::ResumableResult<void>
clear(colorType color = html::Black);
clear(C color = html::Black);

// ##################################################################
// HACK Can't inherit modm::graphic::RemotePainter using RF
Expand All @@ -159,6 +149,9 @@ class Ili9341 : public Interface,
protected:
modm::ResumableResult<void>
drawQuadPoints(Point center, Point point);
private:
// Static variables for resumable functions
Section section;
// ##################################################################

protected:
Expand All @@ -181,10 +174,17 @@ class Ili9341 : public Interface,
modm::ResumableResult<void>
drawFast(Section section);

modm::ResumableResult<colorType>
modm::ResumableResult<C>
getFast(Point point) const;

private:
// Static variables for resumable functions
void scannerNextRow() {
p.scanner.x++;
p.scanner.y = this->clipping.topLeft.y;
}

// OPTIMIZE make a final check, if the union/struct/union is great enough
union {
// Buffers for commands & configuration
uint8_t buff_cmd8[15];
Expand All @@ -194,24 +194,19 @@ class Ili9341 : public Interface,
// Parallel use in resumable function: don't overlap!
struct
{
uint16_t buff_cmd_clipping[2];

// Primary Pixelbuffer
colorType buffer[BC];
size_t buffer_i;
MonochromeReader mono_reader; // Helper to read monochrome data

size_t pixels_to_write, pixel_bulk;
C buffer[BC]; // Bulk buffer
size_t i; // Bulk buffer index
Point scanner; // display index

// Keep track of current position in
Point scanner;
ScannerBufferBool bool_scanner;
size_t pixels; // Pixels of whole transaction
size_t pixels_bulk; // Pixels of current bulk

colorType temp_color;
uint16_t buff_cmd_clipping[2];
C temp_color; // Temporary storage for a color
} p; // p for parallel
};

// BUG Static variables for resumable functions RemotePainter
Section section;
};

} // namespace modm
Expand Down
165 changes: 86 additions & 79 deletions src/modm/driver/display/ili9341_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ modm::Ili9341<Interface, Reset, BC>::updateClipping()
RF_CALL(this->writeCommand(Command::ColumnAddressSet, (uint8_t *)(p.buff_cmd_clipping), 4));

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

RF_END();
}
Expand All @@ -248,111 +248,109 @@ modm::Ili9341<Interface, Reset, BC>::writePattern(Rectangle rectangle, P pattern

p.scanner = this->clipping.topLeft;

while (p.pixels_to_write)
while (p.pixels)
{
// Generate next bulk
for(p.buffer_i = 0; p.buffer_i < std::min<uint32_t>(p.pixels_to_write, BC); p.buffer_i++) {
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
// OPTIMIZE inefficient, cause pattern recalculates color for each pixel
// Let's investigate a solution
p.buffer[p.buffer_i] = pattern(p.scanner);

// Update scanner
// even when it could already know, under withc conditions the return-value changes!
// Need some kind of caching!?
p.buffer[p.i] = pattern(p.scanner);

if (++p.scanner.y == this->clipping.bottomRight.y) {
p.scanner.x++;
p.scanner.y = this->clipping.topLeft.y;
scannerNextRow();
}
}

// Transfer
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.buffer_i));

p.pixels_to_write-= p.buffer_i;
RF_CALL(this->writeData(p.buffer, p.i));
p.pixels-= p.i;
}

RF_END();
}

// -- Write equal colored Buffer ----------------------------------
// -- Write equal colored BufferInterface -----------------------------
template<class Interface, class Reset, size_t BC>
template<typename R_, class Painter_>
modm::ResumableResult<void>
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
const Buffer<colorType, R_, Painter_> &buffer, Point origin)
{
const BufferInterface<C> *buffer, Point origin) {
RF_BEGIN();

this->clipping = this->getIntersection(Rectangle(origin, R_::asPoint()));
this->layout = buffer->getLayout();

this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
RF_CALL(updateClipping());

// FIXME take this->clipping into account
RF_CALL(this->writeData(buffer.getPlainBuffer(), p.pixels_to_write * 2));
// Add left offset
if(origin.x < 0)
this->layout.buffer += -origin.x * this->layout.size.y * 2;

// Check if we exceed the display vertically
if (origin.y < 0 or origin.y + this->layout.size.y != this->clipping.bottomRight.y)
{
// Add top offset
if(origin.y < 0)
this->layout.buffer += -origin.y * 2;

// Can't transfer buffer continuously, send row by row
p.pixels_bulk = this->clipping.getHeight();
while(p.pixels) {
RF_CALL(this->writeData((C*)(this->layout.buffer), p.pixels_bulk));
this->layout.buffer += this->layout.size.y * 2;
p.pixels -= p.pixels_bulk;
}
} else
{
// Transfer buffer continuously in one shot
RF_CALL(this->writeData((C*)(this->layout.buffer), p.pixels));
}

RF_END();
}

// -- Write equal colored BufferInterface -----------------------------
// -- Write different colored BufferInterface -----------------------------
template<class Interface, class Reset, size_t BC>
template<Color C_>
modm::ResumableResult<void>
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
const BufferInterface<colorType> *buffer, Point origin) {
const BufferInterface<C_> *buffer, Point origin) {
RF_BEGIN();

this->clipping = this->getIntersection(Rectangle(origin, buffer->getResolution()));
this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
RF_CALL(updateClipping());

// Reload scanner
p.bool_scanner = ScannerBufferBool(origin);
p.bool_scanner.print_top();
p.bool_scanner.print_state();

RF_END();
}

// -- Write monochrome Buffer -----------------------------
// -- Write monochrome BufferInterface -------------------
template<class Interface, class Reset, size_t BC>
template<typename R_, class Painter_>
modm::ResumableResult<void>
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
const Buffer<bool, R_, Painter_> &buffer, Point origin)
{
const BufferInterface<bool> *buffer, Point origin) {
RF_BEGIN();

// Reload scanner
p.bool_scanner = ScannerBufferBool(buffer.getPlainBuffer(), origin);
p.bool_scanner.print_top();

this->clipping = this->getIntersection(Rectangle(origin, R_::asPoint()));
this->layout = buffer->getLayout();
this->clipping = this->getIntersection(Rectangle(origin, this->layout.size));
RF_CALL(updateClipping());

while (p.pixels_to_write)
p.mono_reader = MonochromeReader(this->layout.buffer, this->layout.size.x, origin);
p.scanner = this->clipping.topLeft;

while (p.pixels)
{
p.temp_color = html::Red;

// Convert next Bulk
p.pixel_bulk = std::min<size_t>(p.pixels_to_write, BC);
for(p.buffer_i = 0; p.buffer_i < p.pixel_bulk; p.buffer_i++) {
// p.bool_scanner.print_state();
// p.buffer[p.buffer_i] = p.bool_scanner() ? color : colorType(html::Black);
p.temp_color.color++;
p.buffer[p.buffer_i] = p.temp_color;
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
p.buffer[p.i] = p.mono_reader() ? color : C(html::Black);
if (++p.scanner.y == this->clipping.bottomRight.y) {
scannerNextRow();
p.mono_reader.nextRow();
}
}

// Transfer
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixel_bulk));
p.pixels_to_write -= p.pixel_bulk;
RF_CALL(this->writeData(p.buffer, p.i));
p.pixels -= p.i;
}
RF_END();
}

// -- Write monochrome BufferInterface -------------------
template<class Interface, class Reset, size_t BC>
modm::ResumableResult<void>
modm::Ili9341<Interface, Reset, BC>::writeBuffer(
const BufferInterface<bool> *buffer, Point origin) {
RF_BEGIN();

MODM_LOG_DEBUG << __FUNCTION__ << modm::endl;
MODM_LOG_DEBUG << "origin: " << origin << ", resolution: " << buffer->getResolution() << modm::endl;

RF_END();
}

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

this->clipping = this->getIntersection(Rectangle(origin, Point(width, height)));
this->clipping = this->getIntersection(Rectangle(origin, {width, height}));
RF_CALL(updateClipping());

// Reload scanner
// p.bool_scanner = ScannerBufferBool(data, origin);
// p.bool_scanner.print_top();
// p.bool_scanner.print_state();

(void)data;
(void)width;
(void)height;
(void)origin;
// FIXME MonochromeReader must learn to handle modm::accessor::Flash<uint8_t>
// p.mono_reader = MonochromeReader(data, width, origin);
p.scanner = this->clipping.topLeft;

while (p.pixels)
{
// Convert next Bulk
for(p.i = 0; p.i < std::min<uint32_t>(p.pixels, BC); p.i++) {
// p.buffer[p.i] = p.mono_reader() ? color : C(html::Black);
if (++p.scanner.y == this->clipping.bottomRight.y) {
scannerNextRow();
// p.mono_reader.nextRow();
}
}
// Transfer
RF_CALL(this->writeData(p.buffer, p.i));
p.pixels -= p.i;
}

RF_END();
RF_END();
}

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

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

while (p.pixels_to_write)
while (p.pixels)
{
p.pixels_to_write -= p.pixel_bulk;
RF_CALL(this->writeData((uint8_t *)(p.buffer), 2 * p.pixel_bulk));
p.pixel_bulk = std::min<size_t>(BC, p.pixels_to_write);
p.pixels -= p.pixels_bulk;
RF_CALL(this->writeData(p.buffer, p.pixels_bulk));
p.pixels_bulk = std::min<size_t>(BC, p.pixels);
}
RF_END();
}

template<class Interface, class Reset, size_t BC>
modm::ResumableResult<void>
modm::Ili9341<Interface, Reset, BC>::clear(colorType color)
modm::Ili9341<Interface, Reset, BC>::clear(C color)
{
// OPTIMIZE Make this impossible fast through use of DMA
// See https://github.com/modm-io/modm/issues/666
Expand Down
Loading

0 comments on commit ca385fc

Please sign in to comment.