Skip to content

Commit b59ef22

Browse files
committed
refactor: Changed LcdInitCommands to not require explicit length
1 parent 71cf510 commit b59ef22

File tree

18 files changed

+268
-277
lines changed

18 files changed

+268
-277
lines changed

components/display_drivers/example/main/display_drivers_example.cpp

+14-18
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,23 @@ static void IRAM_ATTR lcd_spi_post_transfer_callback(spi_transaction_t *t) {
8080

8181
//! [polling_transmit example]
8282
#ifdef CONFIG_DISPLAY_QUAD_SPI
83-
extern "C" void IRAM_ATTR write_command(uint8_t command, const uint8_t *parameters, size_t length,
83+
extern "C" void IRAM_ATTR write_command(uint8_t command, std::span<const uint8_t> parameters,
8484
uint32_t user_data) {
8585
static spi_transaction_t t = {};
8686

8787
t.cmd = static_cast<uint8_t>(DisplayDriver::TransferMode::SINGLE_LINE);
8888
t.addr = static_cast<uint32_t>(command) << 8;
8989
t.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR;
90-
if (length > 0) {
91-
for (size_t i = 0; i < length; i++) {
92-
t.tx_data[i] = parameters[i];
93-
}
94-
t.length = length * 8;
95-
t.flags = SPI_TRANS_MULTILINE_CMD | SPI_TRANS_MULTILINE_ADDR | SPI_TRANS_USE_TXDATA;
96-
} else {
97-
t.tx_buffer = nullptr;
98-
t.length = 0;
99-
}
90+
t.length = parameters.size() * 8;
10091
t.user = reinterpret_cast<void *>(user_data);
10192

93+
if (!parameters.empty() && parameters.size() <= 4) {
94+
memcpy(t.tx_data, parameters.data(), parameters.size());
95+
t.flags |= SPI_TRANS_USE_TXDATA;
96+
} else if (!parameters.empty()) {
97+
t.tx_buffer = parameters.data();
98+
}
99+
102100
auto ret = spi_device_acquire_bus(spi, portMAX_DELAY);
103101
if (ret != ESP_OK) {
104102
fmt::print("Failed to acquire bus: {}\n", esp_err_to_name(ret));
@@ -112,24 +110,22 @@ extern "C" void IRAM_ATTR write_command(uint8_t command, const uint8_t *paramete
112110
spi_device_release_bus(spi);
113111
}
114112
#else
115-
extern "C" void IRAM_ATTR write_command(uint8_t command, const uint8_t *data, size_t length,
113+
extern "C" void IRAM_ATTR write_command(uint8_t command, std::span<const uint8_t> parameters,
116114
uint32_t user_data) {
117-
static spi_transaction_t t;
118-
memset(&t, 0, sizeof(t));
115+
static spi_transaction_t t = {};
119116
t.length = 8;
120117
t.tx_buffer = &command;
121118
t.user = reinterpret_cast<void *>(user_data);
122-
if (length > 0) {
119+
if (!parameters.empty()) {
123120
spi_device_polling_transmit(spi, &t);
124-
t.length = length * 8;
125-
t.tx_buffer = data;
121+
t.length = parameters.size() * 8;
122+
t.tx_buffer = parameters.data();
126123
t.user = reinterpret_cast<void *>(
127124
user_data | (1 << static_cast<int>(espp::display_drivers::Flags::DC_LEVEL_BIT)));
128125
}
129126
spi_device_polling_transmit(spi, &t);
130127
}
131128
#endif
132-
133129
//! [polling_transmit example]
134130

135131
//! [queued_transmit example]

components/display_drivers/include/display_drivers.hpp

+6-8
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@ namespace display_drivers {
99
/**
1010
* @brief Low-level callback to write bytes to the display controller.
1111
* @param command to write
12-
* @param data Pointer to array of command parameters to write.
13-
* @param length Number of command parameters to write.
12+
* @param parameters The command parameters to write
1413
* @param user_data User data associated with this transfer, used for flags.
1514
*/
16-
typedef std::function<void(uint8_t command, const uint8_t *parameters, size_t length,
15+
typedef std::function<void(uint8_t command, std::span<const uint8_t> parameters,
1716
uint32_t user_data)>
1817
write_command_fn;
1918

@@ -76,11 +75,10 @@ enum class Flags {
7675
/**
7776
* @brief Command structure for initializing the lcd
7877
*/
79-
template <typename Command = uint8_t> struct LcdInitCmd {
80-
Command command; /**< Command byte */
81-
uint8_t data[16] = {}; /**< Data bytes */
82-
uint8_t length = 0; /**< Number of data bytes; */
83-
size_t delay_ms = 0; /**< Delay in milliseconds after sending the command. */
78+
template <typename Command = uint8_t> struct DisplayInitCmd {
79+
Command command; /**< Command byte */
80+
std::vector<uint8_t> parameters; /**< Optional command parameters */
81+
size_t delay_ms = 0; /**< Delay in milliseconds after sending the command. */
8482
};
8583

8684
/**

components/display_drivers/include/gc9a01.hpp

+64-64
Original file line numberDiff line numberDiff line change
@@ -125,68 +125,68 @@ class Gc9a01 {
125125
}
126126

127127
// init the display
128-
auto init_commands = std::to_array<display_drivers::LcdInitCmd<>>({
129-
{0xEF, {0}, 0},
130-
{0xEB, {0x14}, 1},
131-
{0xFE, {0}, 0},
132-
{0xEF, {0}, 0},
133-
{0xEB, {0x14}, 1},
134-
{0x84, {0x40}, 1},
135-
{0x85, {0xFF}, 1},
136-
{0x86, {0xFF}, 1},
137-
{0x87, {0xFF}, 1},
138-
{0x88, {0x0A}, 1},
139-
{0x89, {0x21}, 1},
140-
{0x8A, {0x00}, 1},
141-
{0x8B, {0x80}, 1},
142-
{0x8C, {0x01}, 1},
143-
{0x8D, {0x01}, 1},
144-
{0x8E, {0xFF}, 1},
145-
{0x8F, {0xFF}, 1},
146-
{0xB6, {0x00, 0x20}, 2},
128+
auto init_commands = std::to_array<display_drivers::DisplayInitCmd<>>({
129+
{0xEF},
130+
{0xEB, {0x14}},
131+
{0xFE},
132+
{0xEF},
133+
{0xEB, {0x14}},
134+
{0x84, {0x40}},
135+
{0x85, {0xFF}},
136+
{0x86, {0xFF}},
137+
{0x87, {0xFF}},
138+
{0x88, {0x0A}},
139+
{0x89, {0x21}},
140+
{0x8A, {0x00}},
141+
{0x8B, {0x80}},
142+
{0x8C, {0x01}},
143+
{0x8D, {0x01}},
144+
{0x8E, {0xFF}},
145+
{0x8F, {0xFF}},
146+
{0xB6, {0x00, 0x20}},
147147
// call orientation
148-
{0x36, {madctl}, 1},
149-
{0x3A, {0x05}, 1},
150-
{0x90, {0x08, 0x08, 0X08, 0X08}, 4},
151-
{0xBD, {0x06}, 1},
152-
{0xBC, {0x00}, 1},
153-
{0xFF, {0x60, 0x01, 0x04}, 3},
154-
{0xC3, {0x13}, 1},
155-
{0xC4, {0x13}, 1},
156-
{0xC9, {0x22}, 1},
157-
{0xBE, {0x11}, 1},
158-
{0xE1, {0x10, 0x0E}, 2},
159-
{0xDF, {0x21, 0x0C, 0x02}, 3},
160-
{0xF0, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}, 6},
161-
{0xF1, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}, 6},
162-
{0xF2, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}, 6},
163-
{0xF3, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}, 6},
164-
{0xED, {0x1B, 0x0B}, 2},
165-
{0xAE, {0x77}, 1},
166-
{0xCD, {0x63}, 1},
167-
{0x70, {0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0X08, 0x03}, 9},
168-
{0xE8, {0x34}, 1},
169-
{0x62, {0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0X0F, 0x71, 0xEF, 0x70, 0x70}, 12},
170-
{0x63, {0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0X13, 0x71, 0xF3, 0x70, 0x70}, 12},
171-
{0x64, {0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07}, 7},
172-
{0x66, {0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0X00, 0x00, 0x00}, 10},
173-
{0x67, {0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0X10, 0x32, 0x98}, 10},
174-
{0x74, {0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00}, 7},
175-
{0x98, {0x3E, 0x07}, 2},
176-
{0x35, {0}, 0},
177-
{0x21, {0}, 0},
178-
{0x11, {0}, 100},
179-
{0x29, {0}, 100},
148+
{0x36, {madctl}},
149+
{0x3A, {0x05}},
150+
{0x90, {0x08, 0x08, 0X08, 0X08}},
151+
{0xBD, {0x06}},
152+
{0xBC, {0x00}},
153+
{0xFF, {0x60, 0x01, 0x04}},
154+
{0xC3, {0x13}},
155+
{0xC4, {0x13}},
156+
{0xC9, {0x22}},
157+
{0xBE, {0x11}},
158+
{0xE1, {0x10, 0x0E}},
159+
{0xDF, {0x21, 0x0C, 0x02}},
160+
{0xF0, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}},
161+
{0xF1, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}},
162+
{0xF2, {0x45, 0x09, 0x08, 0x08, 0x26, 0x2A}},
163+
{0xF3, {0x43, 0x70, 0x72, 0x36, 0x37, 0x6F}},
164+
{0xED, {0x1B, 0x0B}},
165+
{0xAE, {0x77}},
166+
{0xCD, {0x63}},
167+
{0x70, {0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0X08, 0x03}},
168+
{0xE8, {0x34}},
169+
{0x62, {0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0X0F, 0x71, 0xEF, 0x70, 0x70}},
170+
{0x63, {0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0X13, 0x71, 0xF3, 0x70, 0x70}},
171+
{0x64, {0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07}},
172+
{0x66, {0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0X00, 0x00, 0x00}},
173+
{0x67, {0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0X10, 0x32, 0x98}},
174+
{0x74, {0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00}},
175+
{0x98, {0x3E, 0x07}},
176+
{0x35},
177+
{0x21},
178+
{0x11, {}, 100},
179+
{0x29, {}, 100},
180180
});
181181

182182
// send the init commands
183183
send_commands(init_commands);
184184

185185
// configure the display color configuration
186186
if (config.invert_colors) {
187-
write_command_(static_cast<uint8_t>(Command::invon), nullptr, 0, 0);
187+
write_command_(static_cast<uint8_t>(Command::invon), {}, 0);
188188
} else {
189-
write_command_(static_cast<uint8_t>(Command::invoff), nullptr, 0, 0);
189+
write_command_(static_cast<uint8_t>(Command::invoff), {}, 0);
190190
}
191191
}
192192

@@ -233,7 +233,7 @@ class Gc9a01 {
233233
break;
234234
}
235235
std::scoped_lock lock{spi_mutex_};
236-
write_command_(static_cast<uint8_t>(Command::madctl), &data, 1, 0);
236+
write_command_(static_cast<uint8_t>(Command::madctl), {&data, 1}, 0);
237237
}
238238

239239
/**
@@ -265,7 +265,7 @@ class Gc9a01 {
265265
* @param ye Ending y coordinate of the area.
266266
*/
267267
static void set_drawing_area(size_t xs, size_t ys, size_t xe, size_t ye) {
268-
uint8_t data[4] = {0};
268+
std::array<uint8_t, 4> data;
269269

270270
int offset_x = 0;
271271
int offset_y = 0;
@@ -281,14 +281,14 @@ class Gc9a01 {
281281
data[1] = start_x & 0xFF;
282282
data[2] = (end_x >> 8) & 0xFF;
283283
data[3] = end_x & 0xFF;
284-
write_command_(static_cast<uint8_t>(Command::caset), data, 4, 0);
284+
write_command_(static_cast<uint8_t>(Command::caset), data, 0);
285285

286286
// Set the row (y) start / end addresses
287287
data[0] = (start_y >> 8) & 0xFF;
288288
data[1] = start_y & 0xFF;
289289
data[2] = (end_y >> 8) & 0xFF;
290290
data[3] = end_y & 0xFF;
291-
write_command_(static_cast<uint8_t>(Command::raset), data, 4, 0);
291+
write_command_(static_cast<uint8_t>(Command::raset), data, 0);
292292
}
293293

294294
/**
@@ -311,7 +311,7 @@ class Gc9a01 {
311311
} else {
312312
set_drawing_area(area);
313313
uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
314-
write_command_(static_cast<uint8_t>(Command::ramwr), color_map, size * 2, flags);
314+
write_command_(static_cast<uint8_t>(Command::ramwr), {color_map, size * 2}, flags);
315315
}
316316
}
317317

@@ -332,22 +332,22 @@ class Gc9a01 {
332332
uint16_t color_data[max_bytes_to_send];
333333
memset(color_data, color, max_bytes_to_send * sizeof(uint16_t));
334334
for (int i = 0; i < size; i += max_bytes_to_send) {
335-
int num_bytes = std::min(static_cast<int>(size - i), (int)(max_bytes_to_send));
336-
write_command_(static_cast<uint8_t>(Command::ramwr), reinterpret_cast<uint8_t *>(color_data),
337-
num_bytes * 2, 0);
335+
size_t num_bytes = std::min(static_cast<int>(size - i), (int)(max_bytes_to_send));
336+
write_command_(static_cast<uint8_t>(Command::ramwr),
337+
{reinterpret_cast<uint8_t *>(color_data), num_bytes * 2}, 0);
338338
}
339339
}
340340

341341
/**
342342
* @brief Send the provided commands to the display controller.
343343
* @param commands Array of display_drivers::LcdInitCmd structures.
344344
*/
345-
static void send_commands(std::span<display_drivers::LcdInitCmd<>> commands) {
345+
static void send_commands(std::span<const display_drivers::DisplayInitCmd<>> commands) {
346346
using namespace std::chrono_literals;
347347

348-
for (const auto &[command, data, length, delay_ms] : commands) {
348+
for (const auto &[command, parameters, delay_ms] : commands) {
349349
std::scoped_lock lock{spi_mutex_};
350-
write_command_(command, data, length, 0);
350+
write_command_(command, parameters, 0);
351351
std::this_thread::sleep_for(delay_ms * 1ms);
352352
}
353353
}

0 commit comments

Comments
 (0)