Last active
June 5, 2023 11:01
-
-
Save hollyhockberry/f35a19b61c9fe2a1026efcb30c87bd79 to your computer and use it in GitHub Desktop.
Sample: Porting LovyanGFX to 'Seeed Studio Round Display for XIAO' with XIAO ESP32S3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#include <Arduino.h> | |
#define LGFX_USE_V1 | |
#include <SPIFFS.h> | |
#include <LovyanGFX.hpp> | |
namespace { | |
struct Touch_XiaoRound : public lgfx::v1::ITouch { | |
Touch_XiaoRound() { | |
_cfg.x_min = _cfg.y_min = 0; | |
_cfg.x_max = _cfg.y_max = 239; | |
_cfg.i2c_addr = 0x2e; | |
} | |
bool init() override { | |
if (isSPI()) { | |
return false; | |
} | |
if (_cfg.pin_int >= 0) { | |
lgfx::pinMode(_cfg.pin_int, lgfx::v1::pin_mode_t::input_pullup); | |
} | |
return lgfx::i2c::init(_cfg.i2c_port, _cfg.pin_sda, _cfg.pin_scl).has_value(); | |
} | |
void wakeup() override {} | |
void sleep() override {} | |
uint_fast8_t getTouchRaw(lgfx::v1::touch_point_t *tp, uint_fast8_t count) override { | |
tp[0].size = 0; | |
tp[0].id = 0; | |
if (_cfg.pin_int < 0) { | |
return 0; | |
} | |
//FIXME: | |
if ((bool)lgfx::gpio_in(_cfg.pin_int)) { | |
::delay(10); | |
if ((bool)lgfx::gpio_in(_cfg.pin_int)) { | |
return 0; | |
} | |
} | |
uint8_t buf[5]; | |
if (!lgfx::i2c::transactionRead(_cfg.i2c_port, _cfg.i2c_addr, buf, 5, _cfg.freq).has_value()) { | |
return 0; | |
} | |
if (buf[0] != 1) { | |
return 0; | |
} | |
tp[0].x = buf[2]; | |
tp[0].y = buf[4]; | |
tp[0].size = 1; | |
return 1; | |
} | |
}; | |
class XiaoRoundDisplay : public lgfx::LGFX_Device { | |
lgfx::Panel_GC9A01 _panel; | |
lgfx::Bus_SPI _bus; | |
lgfx::Light_PWM _light; | |
Touch_XiaoRound _touch; | |
public: | |
XiaoRoundDisplay() { | |
auto bus_cfg = _bus.config(); | |
bus_cfg.spi_host = SPI3_HOST; | |
bus_cfg.spi_mode = 0; | |
bus_cfg.freq_write = 40000000; | |
bus_cfg.freq_read = 20000000; | |
bus_cfg.spi_3wire = true; | |
bus_cfg.use_lock = true; | |
bus_cfg.dma_channel = 0; | |
bus_cfg.pin_sclk = 7; | |
bus_cfg.pin_mosi = 9; | |
bus_cfg.pin_miso = 8; | |
bus_cfg.pin_dc = 4; | |
_bus.config(bus_cfg); | |
_panel.setBus(&_bus); | |
auto panel_cfg = _panel.config(); | |
panel_cfg.pin_cs = 2; | |
panel_cfg.pin_rst = -1; | |
panel_cfg.pin_busy = -1; | |
panel_cfg.memory_width = 240; | |
panel_cfg.memory_height = 240; | |
panel_cfg.panel_width = 240; | |
panel_cfg.panel_height = 240; | |
panel_cfg.offset_x = 0; | |
panel_cfg.offset_y = 0; | |
panel_cfg.offset_rotation = 0; | |
panel_cfg.dummy_read_pixel = 8; | |
panel_cfg.dummy_read_bits = 1; | |
panel_cfg.readable = false; | |
panel_cfg.invert = true; | |
panel_cfg.rgb_order = false; | |
panel_cfg.dlen_16bit = false; | |
panel_cfg.bus_shared = true; | |
_panel.config(panel_cfg); | |
auto light_cfg = _light.config(); | |
light_cfg.pin_bl = 43; | |
light_cfg.invert = false; | |
light_cfg.freq = 44100; | |
light_cfg.pwm_channel = 7; | |
_light.config(light_cfg); | |
_panel.setLight(&_light); | |
auto touch_cfg = _touch.config(); | |
touch_cfg.pin_int = 44; | |
touch_cfg.i2c_port = 0; | |
touch_cfg.pin_sda = 5; | |
touch_cfg.pin_scl = 6; | |
touch_cfg.freq = 400000; | |
_touch.config(touch_cfg); | |
_panel.setTouch(&_touch); | |
setPanel(&_panel); | |
} | |
} display; | |
LGFX_Sprite record(&display); | |
float angle = -1.f; | |
void draw(float curr) { | |
if (curr == angle) { | |
return; | |
} | |
curr = ::fmod(curr, 360.f); | |
if (curr < 0.f) { | |
curr += 360.f; | |
} else if (curr >= 360.f) { | |
curr -= 360.f; | |
} | |
angle = curr; | |
display.startWrite(); | |
record.pushRotateZoom( | |
record.width() / 2, record.height() / 2, angle, 1.f, 1.f, TFT_BLACK); | |
display.endWrite(); | |
display.waitDisplay(); | |
} | |
float calcAngle(float x1, float y1, float x2, float y2) { | |
return ::atan2(x1 * y2 - y1 * x2, x1 * x2 + y1 * y2) * 180.f / PI; | |
} | |
} // namespace | |
void setup() { | |
SPIFFS.begin(); | |
display.init(); | |
record.createSprite(240, 240); | |
// need sample.bmp(240x240 pixels) on SPIFFS | |
record.drawBmpFile(SPIFFS, "/sample.bmp", 0, 0); | |
draw(0.f); | |
} | |
void loop() { | |
static bool hold = false; | |
static int32_t _lastx, _lasty; | |
int32_t x, y; | |
if (display.getTouch(&x, &y)) { | |
x -= display.width() / 2; | |
y -= display.height() / 2; | |
if (hold) { | |
auto delta = calcAngle(_lastx, _lasty, x, y); | |
if (!::isnan(delta)) { | |
::draw(angle + delta); | |
} | |
} else { | |
hold = true; | |
} | |
_lastx = x; | |
_lasty = y; | |
} else if (hold) { | |
hold = false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment