-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathwrover-kit.hpp
196 lines (169 loc) · 7.91 KB
/
wrover-kit.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <driver/gpio.h>
#include <driver/spi_master.h>
#include <hal/spi_types.h>
#include "base_component.hpp"
#include "ili9341.hpp"
namespace espp {
/// The WroverKit class provides an interface to the ESP32-WROVER-KIT ESP32
/// development board.
///
/// The class provides access to the following features:
/// - Display
///
/// The class is a singleton and can be accessed using the get() method.
///
/// \section wrover_kit_example Example
/// \snippet wrover_kit_example.cpp wrover-kit example
class WroverKit : public BaseComponent {
public:
/// Alias for the pixel type used by the wrover-kit display
using Pixel = lv_color16_t;
/// The data structure for the touchpad
struct TouchpadData {
uint8_t num_touch_points = 0; ///< The number of touch points
uint16_t x = 0; ///< The x coordinate
uint16_t y = 0; ///< The y coordinate
uint8_t btn_state = 0; ///< The button state (0 = button released, 1 = button pressed)
/// @brief Compare two TouchpadData objects for equality
/// @param rhs The right hand side of the comparison
/// @return true if the two TouchpadData objects are equal, false otherwise
bool operator==(const TouchpadData &rhs) const = default;
};
/// @brief Access the singleton instance of the WroverKit class
/// @return Reference to the singleton instance of the WroverKit class
static WroverKit &get() {
static WroverKit instance;
return instance;
}
WroverKit(const WroverKit &) = delete;
WroverKit &operator=(const WroverKit &) = delete;
WroverKit(WroverKit &&) = delete;
WroverKit &operator=(WroverKit &&) = delete;
/////////////////////////////////////////////////////////////////////////////
// Display
/////////////////////////////////////////////////////////////////////////////
/// Initialize the LCD (low level display driver)
/// \return true if the LCD was successfully initialized, false otherwise
bool initialize_lcd();
/// Initialize the display (lvgl display driver)
/// \param pixel_buffer_size The size of the pixel buffer
/// \param task_config The task configuration for the display task
/// \param update_period_ms The update period of the display task
/// \return true if the display was successfully initialized, false otherwise
/// \note This will also allocate two full frame buffers in the SPIRAM
bool initialize_display(size_t pixel_buffer_size,
const espp::Task::BaseConfig &task_config = {.name = "Display",
.stack_size_bytes = 4096,
.priority = 10,
.core_id = 0},
int update_period_ms = 16);
/// Get the width of the LCD in pixels
/// \return The width of the LCD in pixels
static constexpr size_t lcd_width() { return lcd_width_; }
/// Get the height of the LCD in pixels
/// \return The height of the LCD in pixels
static constexpr size_t lcd_height() { return lcd_height_; }
/// Get the GPIO pin for the LCD data/command signal
/// \return The GPIO pin for the LCD data/command signal
static constexpr auto get_lcd_dc_gpio() { return lcd_dc_io; }
/// Get a shared pointer to the display
/// \return A shared pointer to the display
std::shared_ptr<Display<Pixel>> display() const;
/// Set the brightness of the backlight
/// \param brightness The brightness of the backlight as a percentage (0 - 100)
void brightness(float brightness);
/// Get the brightness of the backlight
/// \return The brightness of the backlight as a percentage (0 - 100)
float brightness() const;
/// Get the VRAM 0 pointer (DMA memory used by LVGL)
/// \return The VRAM 0 pointer
/// \note This is the memory used by LVGL for rendering
/// \note This is null unless initialize_display() has been called
Pixel *vram0() const;
/// Get the VRAM 1 pointer (DMA memory used by LVGL)
/// \return The VRAM 1 pointer
/// \note This is the memory used by LVGL for rendering
/// \note This is null unless initialize_display() has been called
Pixel *vram1() const;
/// Get the frame buffer 0 pointer
/// \return The frame buffer 0 pointer
/// \note This memory is designed to be used by the application developer and
/// is provided as a convenience. It is not used by the display driver.
/// \note This is null unless initialize_display() has been called
uint8_t *frame_buffer0() const;
/// Get the frame buffer 1 pointer
/// \return The frame buffer 1 pointer
/// \note This memory is designed to be used by the application developer and
/// is provided as a convenience. It is not used by the display driver.
/// \note This is null unless initialize_display() has been called
uint8_t *frame_buffer1() const;
/// Write data to the LCD
/// \param data The data to write
/// \param length The length of the data
/// \param user_data User data to pass to the spi transaction callback
/// \note This method is designed to be used by the display driver
/// \note This method queues the data to be written to the LCD, only blocking
/// if there is an ongoing SPI transaction
void write_lcd(const uint8_t *data, size_t length, uint32_t user_data);
/// Write a frame to the LCD
/// \param x The x coordinate
/// \param y The y coordinate
/// \param width The width of the frame, in pixels
/// \param height The height of the frame, in pixels
/// \param data The data to write
/// \note This method queues the data to be written to the LCD, only blocking
/// if there is an ongoing SPI transaction
void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width,
const uint16_t height, uint8_t *data);
/// Write lines to the LCD
/// \param xs The x start coordinate
/// \param ys The y start coordinate
/// \param xe The x end coordinate
/// \param ye The y end coordinate
/// \param data The data to write
/// \param user_data User data to pass to the spi transaction callback
/// \note This method queues the data to be written to the LCD, only blocking
/// if there is an ongoing SPI transaction
void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data);
protected:
WroverKit();
void lcd_wait_lines();
// common:
// LCD
static constexpr size_t lcd_width_ = 320;
static constexpr size_t lcd_height_ = 240;
static constexpr size_t lcd_bytes_per_pixel = 2;
static constexpr size_t frame_buffer_size = (((lcd_width_)*lcd_bytes_per_pixel) * lcd_height_);
static constexpr int lcd_clock_speed = 20 * 1000 * 1000;
static constexpr auto lcd_spi_num = SPI2_HOST;
static constexpr gpio_num_t lcd_cs_io = GPIO_NUM_22;
static constexpr gpio_num_t lcd_mosi_io = GPIO_NUM_23;
static constexpr gpio_num_t lcd_sclk_io = GPIO_NUM_19;
static constexpr gpio_num_t lcd_reset_io = GPIO_NUM_18;
static constexpr gpio_num_t lcd_dc_io = GPIO_NUM_21;
static constexpr gpio_num_t backlight_io = GPIO_NUM_5;
static constexpr bool backlight_value = false;
static constexpr bool reset_value = false;
static constexpr bool invert_colors = false;
static constexpr auto rotation = espp::DisplayRotation::LANDSCAPE;
static constexpr bool mirror_x = false;
static constexpr bool mirror_y = false;
static constexpr bool swap_xy = true;
using DisplayDriver = espp::Ili9341;
// display
std::shared_ptr<Display<Pixel>> display_;
/// SPI bus for communication with the LCD
spi_bus_config_t lcd_spi_bus_config_;
spi_device_interface_config_t lcd_config_;
spi_device_handle_t lcd_handle_{nullptr};
static constexpr int spi_queue_size = 6;
spi_transaction_t trans[spi_queue_size];
std::atomic<int> num_queued_trans = 0;
uint8_t *frame_buffer0_{nullptr};
uint8_t *frame_buffer1_{nullptr};
}; // class WroverKit
} // namespace espp