Skip to content

Commit 8e201be

Browse files
committed
using 16bit transfer in driver::ili9341
1 parent 5262261 commit 8e201be

File tree

4 files changed

+68
-53
lines changed

4 files changed

+68
-53
lines changed

src/modm/driver/display/ili9341.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,10 @@ class Ili9341 : public Interface, public modm::ColorGraphicDisplay
297297

298298
Orientation orientation{Orientation::Landscape0};
299299

300-
uint8_t buffer[BufferSize * 2]{0};
300+
union {
301+
uint8_t buffer[BufferSize * 2];
302+
modm::color::Rgb565 buffer_rgb565[BufferSize];
303+
};
301304
};
302305

303306
} // namespace modm

src/modm/driver/display/ili9341_impl.hpp

Lines changed: 18 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -202,41 +202,37 @@ void
202202
Ili9341<Interface, Reset, Backlight, BufferSize>::drawHorizontalLine(
203203
glcd::Point start, uint16_t length)
204204
{
205-
uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) };
206205
auto minLength { std::min(std::size_t(length), BufferSize) };
207-
uint16_t *buffer16 { reinterpret_cast<uint16_t *>(buffer) };
208-
std::fill(buffer16, buffer16+minLength, pixelValue);
206+
std::fill(buffer_rgb565, buffer_rgb565+minLength, foregroundColor);
209207

210208
BatchHandle h(*this);
211209

212210
setClipping(start.getX(), start.getY(), length, 1);
213211
while (length > BufferSize)
214212
{
215-
this->writeData(buffer, BufferSize * 2);
213+
this->writeData(buffer_rgb565, BufferSize);
216214
length -= BufferSize;
217215
}
218-
this->writeData(buffer, length * 2);
216+
this->writeData(buffer_rgb565, length);
219217
}
220218

221219
template <class Interface, class Reset, class Backlight, std::size_t BufferSize>
222220
void
223221
Ili9341<Interface, Reset, Backlight, BufferSize>::drawVerticalLine(
224222
glcd::Point start, uint16_t length)
225223
{
226-
uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) };
227224
auto minLength { std::min(std::size_t(length), BufferSize) };
228-
uint16_t *buffer16 { reinterpret_cast<uint16_t *>(buffer) };
229-
std::fill(buffer16, buffer16+minLength, pixelValue);
225+
std::fill(buffer_rgb565, buffer_rgb565+minLength, foregroundColor);
230226

231227
BatchHandle h(*this);
232228

233229
setClipping(start.getX(), start.getY(), 1, length);
234230
while (length > BufferSize)
235231
{
236-
this->writeData(buffer, BufferSize * 2);
232+
this->writeData(buffer_rgb565, BufferSize);
237233
length -= BufferSize;
238234
}
239-
this->writeData(buffer, length * 2);
235+
this->writeData(buffer_rgb565, length);
240236
}
241237

242238
template <class Interface, class Reset, class Backlight, std::size_t BufferSize>
@@ -248,31 +244,25 @@ Ili9341<Interface, Reset, Backlight, BufferSize>::fillRectangle(
248244
auto const y { upperLeft.getY() };
249245
std::size_t pixelCount { std::size_t(width) * std::size_t(height) };
250246

251-
uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) };
252247
auto minLength { std::min(std::size_t(pixelCount), BufferSize) };
253-
uint16_t *buffer16 { reinterpret_cast<uint16_t *>(buffer) };
254-
std::fill(buffer16, buffer16+minLength, pixelValue);
248+
std::fill(buffer_rgb565, buffer_rgb565+minLength, foregroundColor);
255249

256250
BatchHandle h(*this);
257251

258252
setClipping(x, y, width, height);
259253
while (pixelCount > BufferSize)
260254
{
261-
this->writeData(buffer, BufferSize * 2);
255+
this->writeData(buffer_rgb565, BufferSize);
262256
pixelCount -= BufferSize;
263257
}
264-
if (pixelCount)
265-
this->writeData(buffer, pixelCount * 2);
258+
this->writeData(buffer_rgb565, pixelCount);
266259
}
267260

268261
template <class Interface, class Reset, class Backlight, std::size_t BufferSize>
269262
void
270263
Ili9341<Interface, Reset, Backlight, BufferSize>::fillCircle(
271264
glcd::Point center, uint16_t radius)
272265
{
273-
uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff),
274-
uint8_t(foregroundColor.color & 0xff) };
275-
276266
int16_t f = 1 - radius;
277267
int16_t ddF_x = 0;
278268
int16_t ddF_y = -2 * radius;
@@ -283,7 +273,7 @@ Ili9341<Interface, Reset, Backlight, BufferSize>::fillCircle(
283273

284274
setClipping(center.getX() - radius, center.getY(), 2 * radius, 1);
285275
for (std::size_t i = 0; i < 2 * radius; ++i)
286-
this->writeData(setColor, 2);
276+
this->writeData(foregroundColor.color);
287277

288278
while(x < y)
289279
{
@@ -299,16 +289,16 @@ Ili9341<Interface, Reset, Backlight, BufferSize>::fillCircle(
299289

300290
setClipping(center.getX() - x, center.getY() - y, 2 * x, 1);
301291
for (std::size_t i = 0; i < 2 * x; ++i)
302-
this->writeData(setColor, 2);
292+
this->writeData(foregroundColor.color);
303293
setClipping(center.getX() - y, center.getY() - x, 2 * y, 1);
304294
for (std::size_t i = 0; i < 2 * y; ++i)
305-
this->writeData(setColor, 2);
295+
this->writeData(foregroundColor.color);
306296
setClipping(center.getX() - x, center.getY() + y, 2 * x, 1);
307297
for (std::size_t i = 0; i < 2 * x; ++i)
308-
this->writeData(setColor, 2);
298+
this->writeData(foregroundColor.color);
309299
setClipping(center.getX() - y, center.getY() + x, 2 * y, 1);
310300
for (std::size_t i = 0; i < 2 * y; ++i)
311-
this->writeData(setColor, 2);
301+
this->writeData(foregroundColor.color);
312302
}
313303
}
314304

@@ -317,11 +307,6 @@ void
317307
Ili9341<Interface, Reset, Backlight, BufferSize>::drawImageRaw(glcd::Point upperLeft,
318308
uint16_t width, uint16_t height, modm::accessor::Flash<uint8_t> data)
319309
{
320-
uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff),
321-
uint8_t(foregroundColor.color & 0xff) };
322-
uint8_t const clearColor[] { uint8_t((backgroundColor.color >> 8) & 0xff),
323-
uint8_t(backgroundColor.color & 0xff) };
324-
325310
BatchHandle h(*this);
326311

327312
setClipping(upperLeft.getX(), upperLeft.getY(), width, height);
@@ -333,9 +318,9 @@ Ili9341<Interface, Reset, Backlight, BufferSize>::drawImageRaw(glcd::Point upper
333318
{
334319
uint8_t byte = data[(r / 8) * width + w];
335320
if (byte & bit)
336-
this->writeData(setColor, 2);
321+
this->writeData(foregroundColor.color);
337322
else
338-
this->writeData(clearColor, 2);
323+
this->writeData(backgroundColor.color);
339324
}
340325
// TODO: optimize, use ROL (rotate left)
341326
bit <<= 1;
@@ -351,13 +336,8 @@ Ili9341<Interface, Reset, Backlight, BufferSize>::drawRaw(glcd::Point upperLeft,
351336
{
352337
BatchHandle h(*this);
353338

354-
uint16_t* buffer = (uint16_t*)data;
355-
for(size_t i = 0; i < size_t(width*height); i++) {
356-
buffer[i] = modm::fromBigEndian(buffer[i]);
357-
}
358-
359339
setClipping(upperLeft.getX(), upperLeft.getY(), width, height);
360-
this->writeData((uint8_t*)buffer, width * height * 2);
340+
this->writeData(data, width * height);
361341
}
362342

363343
template <class Interface, class Reset, class Backlight, std::size_t BufferSize>
@@ -391,13 +371,10 @@ void
391371
Ili9341<Interface, Reset, Backlight, BufferSize>::setColoredPixel(
392372
int16_t x, int16_t y, color::Rgb565 const &color)
393373
{
394-
auto const pixelColor { color };
395-
uint8_t const setColor[] { uint8_t((pixelColor.color >> 8) & 0xff), uint8_t(pixelColor.color & 0xff) };
396-
397374
BatchHandle h(*this);
398375

399376
this->setClipping(x, y, 1, 1);
400-
this->writeData(setColor, 2);
377+
this->writeData(color);
401378
}
402379

403380
template <class Interface, class Reset, class Backlight, std::size_t BufferSize>

src/modm/driver/display/ili9341_parallel.hpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2020, Pavel Pletenev
3+
* Copyright (c) 2020, Thomas Sommer
34
*
45
* This file is part of the modm project.
56
*
@@ -36,14 +37,20 @@ class Ili9341ParallelInterface: public ili9341
3637
for(std::size_t i=0; i<length; ++i)
3738
interface.writeData(args[i]);
3839
}
40+
41+
void
42+
writeData(color::Rgb565 data)
43+
{
44+
interface.writeData(data.color);
45+
}
46+
3947
void
40-
writeData(uint8_t const *data, std::size_t length)
48+
writeData(color::Rgb565 const *data, std::size_t length)
4149
{
42-
auto const data16 = reinterpret_cast<uint16_t const*>(data);
43-
size_t const length16 = length / 2;
44-
for(std::size_t i=0; i<length16; ++i)
45-
interface.writeData(modm::fromBigEndian(data16[i]));
50+
for(std::size_t i=0; i < length; ++i)
51+
interface.writeData(data[i].color);
4652
}
53+
4754
void
4855
writeCommandValue8(Command command, uint8_t value)
4956
{

src/modm/driver/display/ili9341_spi.hpp

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,40 +21,68 @@ namespace modm
2121
template<class SPI, class Cs, class Dc>
2222
class Ili9341SPIInterface: public ili9341, public modm::SpiDevice<SPI>
2323
{
24+
static constexpr auto configuration8bit = []() {
25+
SpiMaster::setDataMode(SpiMaster::DataMode::Mode0);
26+
SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst);
27+
SpiMaster::setDataSize(SpiMaster::DataSize::Bit8);
28+
};
29+
30+
static constexpr auto configuration16bit = []() {
31+
SpiMaster::setDataMode(SpiMaster::DataMode::Mode0);
32+
SpiMaster::setDataOrder(SpiMaster::DataOrder::MsbFirst);
33+
SpiMaster::setDataSize(SpiMaster::DataSize::Bit16);
34+
};
35+
2436
public:
2537
Ili9341SPIInterface()
2638
{
27-
this->attachConfigurationHandler([]() {
28-
SPI::setDataMode(SPI::DataMode::Mode0);
29-
SPI::setDataOrder(SPI::DataOrder::MsbFirst);
30-
});
39+
this->attachConfigurationHandler(configuration16bit);
3140
Cs::setOutput(modm::Gpio::High);
3241
Dc::setOutput();
3342
}
3443

3544
__attribute__((noinline)) void
3645
writeCommand(Command command)
3746
{
47+
this->attachConfigurationHandler(configuration8bit);
3848
Dc::reset(); // enable command
3949
SPI::transferBlocking(i(command));
4050
Dc::set(); // reset to data
51+
this->attachConfigurationHandler(configuration16bit);
4152
}
4253
__attribute__((noinline)) void
4354
writeCommand(Command command, uint8_t const *args, std::size_t length)
4455
{
56+
this->attachConfigurationHandler(configuration8bit);
4557
Dc::reset(); // enable command
4658
SPI::transferBlocking(i(command));
4759
Dc::set(); // reset to data
4860
if (length != 0)
4961
{
50-
SPI::transferBlocking(const_cast<unsigned char *>(args), nullptr, length);
62+
SPI::transferBlocking(args, (uint8_t*)(nullptr), length);
5163
}
64+
this->attachConfigurationHandler(configuration16bit);
5265
}
5366
void
5467
writeData(uint8_t const *data, std::size_t length)
5568
{
56-
SPI::transferBlocking(const_cast<unsigned char *>(data), nullptr, length);
69+
this->attachConfigurationHandler(configuration8bit);
70+
SPI::transferBlocking(data, (uint8_t*)(nullptr), length);
71+
this->attachConfigurationHandler(configuration16bit);
5772
}
73+
74+
void
75+
writeData(color::Rgb565 data)
76+
{
77+
SPI::transferBlocking(data.color);
78+
}
79+
80+
void
81+
writeData(color::Rgb565 const *data, std::size_t length)
82+
{
83+
SPI::transferBlocking((uint16_t*)(data), (uint16_t*)(nullptr), length);
84+
}
85+
5886
void
5987
writeCommandValue8(Command command, uint8_t value)
6088
{

0 commit comments

Comments
 (0)