Update ArduinoGFX driver

This commit is contained in:
fvanroie 2023-01-11 18:18:21 +01:00
parent dd9c84fcc5
commit b26ea27108
9 changed files with 360 additions and 523 deletions

View File

@ -1,293 +0,0 @@
#include "Arduino_ESP32RGBPanel_mod.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
Arduino_ESP32RGBPanel_Mod::Arduino_ESP32RGBPanel_Mod(
int8_t cs, int8_t sck, int8_t sda,
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
bool useBigEndian)
: _cs(cs), _sck(sck), _sda(sda),
_de(de), _vsync(vsync), _hsync(hsync), _pclk(pclk),
_r0(r0), _r1(r1), _r2(r2), _r3(r3), _r4(r4),
_g0(g0), _g1(g1), _g2(g2), _g3(g3), _g4(g4), _g5(g5),
_b0(b0), _b1(b1), _b2(b2), _b3(b3), _b4(b4),
_useBigEndian(useBigEndian)
{
}
void Arduino_ESP32RGBPanel_Mod::begin(int32_t speed, int8_t dataMode)
{
if (speed == GFX_NOT_DEFINED)
{
#ifdef CONFIG_SPIRAM_MODE_QUAD
_speed = 6000000L;
#else
_speed = 12000000L;
#endif
}
else
{
_speed = speed;
}
UNUSED(dataMode);
if (_cs != GFX_NOT_DEFINED)
{
pinMode(_cs, OUTPUT);
digitalWrite(_cs, HIGH); // disable chip select
}
if (_cs >= 32)
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)&GPIO.out1_w1ts.val;
_csPortClr = (PORTreg_t)&GPIO.out1_w1tc.val;
}
else
{
_csPinMask = digitalPinToBitMask(_cs);
_csPortSet = (PORTreg_t)&GPIO.out_w1ts;
_csPortClr = (PORTreg_t)&GPIO.out_w1tc;
}
if (_sck != GFX_NOT_DEFINED)
{
pinMode(_sck, OUTPUT);
digitalWrite(_sck, LOW);
}
if (_sck >= 32)
{
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = (PORTreg_t)&GPIO.out1_w1ts.val;
_sckPortClr = (PORTreg_t)&GPIO.out1_w1tc.val;
}
else
{
_sckPinMask = digitalPinToBitMask(_sck);
_sckPortSet = (PORTreg_t)&GPIO.out_w1ts;
_sckPortClr = (PORTreg_t)&GPIO.out_w1tc;
}
if (_sda != GFX_NOT_DEFINED)
{
pinMode(_sda, OUTPUT);
digitalWrite(_sda, LOW);
}
if (_sda >= 32)
{
_sdaPinMask = digitalPinToBitMask(_sda);
_sdaPortSet = (PORTreg_t)&GPIO.out1_w1ts.val;
_sdaPortClr = (PORTreg_t)&GPIO.out1_w1tc.val;
}
else
{
_sdaPinMask = digitalPinToBitMask(_sda);
_sdaPortSet = (PORTreg_t)&GPIO.out_w1ts;
_sdaPortClr = (PORTreg_t)&GPIO.out_w1tc;
}
}
void Arduino_ESP32RGBPanel_Mod::beginWrite()
{
CS_LOW();
}
void Arduino_ESP32RGBPanel_Mod::endWrite()
{
CS_HIGH();
}
void Arduino_ESP32RGBPanel_Mod::writeCommand(uint8_t c)
{
// D/C bit, command
SDA_LOW();
SCK_HIGH();
SCK_LOW();
uint8_t bit = 0x80;
while (bit)
{
if (c & bit)
{
SDA_HIGH();
}
else
{
SDA_LOW();
}
SCK_HIGH();
bit >>= 1;
SCK_LOW();
}
}
void Arduino_ESP32RGBPanel_Mod::writeCommand16(uint16_t)
{
}
void Arduino_ESP32RGBPanel_Mod::write(uint8_t d)
{
// D/C bit, data
SDA_HIGH();
SCK_HIGH();
SCK_LOW();
uint8_t bit = 0x80;
while (bit)
{
if (d & bit)
{
SDA_HIGH();
}
else
{
SDA_LOW();
}
SCK_HIGH();
bit >>= 1;
SCK_LOW();
}
}
void Arduino_ESP32RGBPanel_Mod::write16(uint16_t)
{
}
void Arduino_ESP32RGBPanel_Mod::writeRepeat(uint16_t p, uint32_t len)
{
}
void Arduino_ESP32RGBPanel_Mod::writePixels(uint16_t *data, uint32_t len)
{
}
void Arduino_ESP32RGBPanel_Mod::writeBytes(uint8_t *data, uint32_t len)
{
}
void Arduino_ESP32RGBPanel_Mod::writePattern(uint8_t *data, uint8_t len, uint32_t repeat)
{
}
uint16_t *Arduino_ESP32RGBPanel_Mod::getFrameBuffer(
uint16_t w, uint16_t h,
uint16_t hsync_pulse_width, uint16_t hsync_back_porch, uint16_t hsync_front_porch, uint16_t hsync_polarity,
uint16_t vsync_pulse_width, uint16_t vsync_back_porch, uint16_t vsync_front_porch, uint16_t vsync_polarity,
uint16_t pclk_active_neg, int32_t prefer_speed)
{
esp_lcd_rgb_panel_config_t *_panel_config = (esp_lcd_rgb_panel_config_t *)heap_caps_calloc(1, sizeof(esp_lcd_rgb_panel_config_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
_panel_config->clk_src = LCD_CLK_SRC_PLL160M;
_panel_config->timings.pclk_hz = (prefer_speed == GFX_NOT_DEFINED) ? _speed : prefer_speed;
_panel_config->timings.h_res = w;
_panel_config->timings.v_res = h;
// The following parameters should refer to LCD spec
_panel_config->timings.hsync_pulse_width = hsync_pulse_width;
_panel_config->timings.hsync_back_porch = hsync_back_porch;
_panel_config->timings.hsync_front_porch = hsync_front_porch;
_panel_config->timings.vsync_pulse_width = vsync_pulse_width;
_panel_config->timings.vsync_back_porch = vsync_back_porch;
_panel_config->timings.vsync_front_porch = vsync_front_porch;
_panel_config->timings.flags.hsync_idle_low = (hsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.vsync_idle_low = (vsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.de_idle_high = 0;
_panel_config->timings.flags.pclk_active_neg = pclk_active_neg;
_panel_config->timings.flags.pclk_idle_high = 0;
_panel_config->data_width = 16; // RGB565 in parallel mode, thus 16bit in width
_panel_config->sram_trans_align = 8;
_panel_config->psram_trans_align = 64;
_panel_config->hsync_gpio_num = _hsync;
_panel_config->vsync_gpio_num = _vsync;
_panel_config->de_gpio_num = _de;
_panel_config->pclk_gpio_num = _pclk;
if (_useBigEndian)
{
_panel_config->data_gpio_nums[0] = _g3;
_panel_config->data_gpio_nums[1] = _g4;
_panel_config->data_gpio_nums[2] = _g5;
_panel_config->data_gpio_nums[3] = _r0;
_panel_config->data_gpio_nums[4] = _r1;
_panel_config->data_gpio_nums[5] = _r2;
_panel_config->data_gpio_nums[6] = _r3;
_panel_config->data_gpio_nums[7] = _r4;
_panel_config->data_gpio_nums[8] = _b0;
_panel_config->data_gpio_nums[9] = _b1;
_panel_config->data_gpio_nums[10] = _b2;
_panel_config->data_gpio_nums[11] = _b3;
_panel_config->data_gpio_nums[12] = _b4;
_panel_config->data_gpio_nums[13] = _g0;
_panel_config->data_gpio_nums[14] = _g1;
_panel_config->data_gpio_nums[15] = _g2;
}
else
{
_panel_config->data_gpio_nums[0] = _b0;
_panel_config->data_gpio_nums[1] = _b1;
_panel_config->data_gpio_nums[2] = _b2;
_panel_config->data_gpio_nums[3] = _b3;
_panel_config->data_gpio_nums[4] = _b4;
_panel_config->data_gpio_nums[5] = _g0;
_panel_config->data_gpio_nums[6] = _g1;
_panel_config->data_gpio_nums[7] = _g2;
_panel_config->data_gpio_nums[8] = _g3;
_panel_config->data_gpio_nums[9] = _g4;
_panel_config->data_gpio_nums[10] = _g5;
_panel_config->data_gpio_nums[11] = _r0;
_panel_config->data_gpio_nums[12] = _r1;
_panel_config->data_gpio_nums[13] = _r2;
_panel_config->data_gpio_nums[14] = _r3;
_panel_config->data_gpio_nums[15] = _r4;
}
_panel_config->disp_gpio_num = GPIO_NUM_NC;
_panel_config->flags.disp_active_low = 0;
_panel_config->flags.relax_on_idle = 0;
_panel_config->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(_panel_config, &_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_reset(_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(_panel_handle));
uint16_t color = random(0xffff);
ESP_ERROR_CHECK(_panel_handle->draw_bitmap(_panel_handle, 0, 0, 1, 1, &color));
_rgb_panel = __containerof(_panel_handle, esp_rgb_panel_t, base);
return (uint16_t *)_rgb_panel->fb;
}
INLINE void Arduino_ESP32RGBPanel_Mod::CS_HIGH(void)
{
*_csPortSet = _csPinMask;
}
INLINE void Arduino_ESP32RGBPanel_Mod::CS_LOW(void)
{
*_csPortClr = _csPinMask;
}
INLINE void Arduino_ESP32RGBPanel_Mod::SCK_HIGH(void)
{
*_sckPortSet = _sckPinMask;
}
INLINE void Arduino_ESP32RGBPanel_Mod::SCK_LOW(void)
{
*_sckPortClr = _sckPinMask;
}
INLINE void Arduino_ESP32RGBPanel_Mod::SDA_HIGH(void)
{
*_sdaPortSet = _sdaPinMask;
}
INLINE void Arduino_ESP32RGBPanel_Mod::SDA_LOW(void)
{
*_sdaPortClr = _sdaPinMask;
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -1,125 +0,0 @@
#ifdef HASP_USE_ARDUINOGFX
#include "Arduino.h"
#include "Arduino_DataBus.h"
#endif
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#include "databus/Arduino_ESP32RGBPanel.h" // struct esp_rgb_panel_t
#ifndef _ARDUINO_ESP32RGBPANEL_MOD_H_
#define _ARDUINO_ESP32RGBPANEL_MOD_H_
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_rgb.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_interface.h"
#include "esp_private/gdma.h"
#include "esp_pm.h"
#include "hal/dma_types.h"
#include "hal/lcd_hal.h"
#include "hal/lcd_ll.h"
#include "esp32s3/rom/cache.h"
// This function is located in ROM (also see esp_rom/${target}/ld/${target}.rom.ld)
extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);
// // extract from esp-idf esp_lcd_rgb_panel.c
// struct esp_rgb_panel_t
// {
// esp_lcd_panel_t base; // Base class of generic lcd panel
// int panel_id; // LCD panel ID
// lcd_hal_context_t hal; // Hal layer object
// size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16)
// size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
// size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
// int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
// intr_handle_t intr; // LCD peripheral interrupt handle
// esp_pm_lock_handle_t pm_lock; // Power management lock
// size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
// uint8_t *fb; // Frame buffer
// size_t fb_size; // Size of frame buffer
// int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
// size_t resolution_hz; // Peripheral clock resolution
// esp_lcd_rgb_timing_t timings; // RGB timing parameters (e.g. pclk, sync pulse, porch width)
// gdma_channel_handle_t dma_chan; // DMA channel handle
// esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; // Callback, invoked after frame trans done
// void *user_ctx; // Reserved user's data of callback functions
// int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
// int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
// struct
// {
// unsigned int disp_en_level : 1; // The level which can turn on the screen by `disp_gpio_num`
// unsigned int stream_mode : 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done
// unsigned int fb_in_psram : 1; // Whether the frame buffer is in PSRAM
// } flags;
// dma_descriptor_t dma_nodes[]; // DMA descriptor pool of size `num_dma_nodes`
// };
class Arduino_ESP32RGBPanel_Mod : public Arduino_DataBus
{
public:
Arduino_ESP32RGBPanel_Mod(
int8_t cs, int8_t sck, int8_t sda,
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
bool useBigEndian = false);
void begin(int32_t speed = GFX_NOT_DEFINED, int8_t dataMode = GFX_NOT_DEFINED) override;
void beginWrite() override;
void endWrite() override;
void writeCommand(uint8_t) override;
void writeCommand16(uint16_t) override;
void write(uint8_t) override;
void write16(uint16_t) override;
void writeRepeat(uint16_t p, uint32_t len) override;
void writePixels(uint16_t *data, uint32_t len) override;
void writeBytes(uint8_t *data, uint32_t len) override;
void writePattern(uint8_t *data, uint8_t len, uint32_t repeat) override;
uint16_t *getFrameBuffer(
uint16_t w, uint16_t h,
uint16_t hsync_pulse_width = 18, uint16_t hsync_back_porch = 24, uint16_t hsync_front_porch = 6, uint16_t hsync_polarity = 1,
uint16_t vsync_pulse_width = 10, uint16_t vsync_back_porch = 16, uint16_t vsync_front_porch = 4, uint16_t vsync_polarity = 1,
uint16_t pclk_active_neg = 0, int32_t prefer_speed = GFX_NOT_DEFINED);
esp_lcd_panel_handle_t _panel_handle = NULL;
protected:
private:
INLINE void CS_HIGH(void);
INLINE void CS_LOW(void);
INLINE void SCK_HIGH(void);
INLINE void SCK_LOW(void);
INLINE void SDA_HIGH(void);
INLINE void SDA_LOW(void);
int32_t _speed;
int8_t _dataMode;
int8_t _cs, _sck, _sda;
int8_t _de, _vsync, _hsync, _pclk;
int8_t _r0, _r1, _r2, _r3, _r4;
int8_t _g0, _g1, _g2, _g3, _g4, _g5;
int8_t _b0, _b1, _b2, _b3, _b4;
bool _useBigEndian;
esp_rgb_panel_t *_rgb_panel;
PORTreg_t _csPortSet; ///< PORT register for chip select SET
PORTreg_t _csPortClr; ///< PORT register for chip select CLEAR
PORTreg_t _sckPortSet; ///< PORT register for SCK SET
PORTreg_t _sckPortClr; ///< PORT register for SCK CLEAR
PORTreg_t _sdaPortSet; ///< PORT register for SCK SET
PORTreg_t _sdaPortClr; ///< PORT register for SCK CLEAR
uint32_t _csPinMask; ///< Bitmask for chip select
uint32_t _sckPinMask; ///< Bitmask for SCK
uint32_t _sdaPinMask; ///< Bitmask for SCK
};
#endif // _ARDUINO_ESP32RGBPANEL_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -0,0 +1,125 @@
#include "Arduino_RGBPanel_mod.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
Arduino_RGBPanel_Mod::Arduino_RGBPanel_Mod(
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
uint16_t hsync_polarity, uint16_t hsync_front_porch, uint16_t hsync_pulse_width, uint16_t hsync_back_porch,
uint16_t vsync_polarity, uint16_t vsync_front_porch, uint16_t vsync_pulse_width, uint16_t vsync_back_porch,
uint16_t pclk_active_neg, int32_t prefer_speed, bool useBigEndian)
: _de(de), _vsync(vsync), _hsync(hsync), _pclk(pclk),
_r0(r0), _r1(r1), _r2(r2), _r3(r3), _r4(r4),
_g0(g0), _g1(g1), _g2(g2), _g3(g3), _g4(g4), _g5(g5),
_b0(b0), _b1(b1), _b2(b2), _b3(b3), _b4(b4),
_hsync_polarity(hsync_polarity), _hsync_front_porch(hsync_front_porch), _hsync_pulse_width(hsync_pulse_width), _hsync_back_porch(hsync_back_porch),
_vsync_polarity(vsync_polarity), _vsync_front_porch(vsync_front_porch), _vsync_pulse_width(vsync_pulse_width), _vsync_back_porch(vsync_back_porch),
_pclk_active_neg(pclk_active_neg), _prefer_speed(prefer_speed), _useBigEndian(useBigEndian)
{
}
void Arduino_RGBPanel_Mod::begin(int32_t speed)
{
if (speed == GFX_NOT_DEFINED)
{
#ifdef CONFIG_SPIRAM_MODE_QUAD
_speed = 6000000L;
#else
_speed = 12000000L;
#endif
}
else
{
_speed = speed;
}
}
uint16_t *Arduino_RGBPanel_Mod::getFrameBuffer(int16_t w, int16_t h)
{
esp_lcd_rgb_panel_config_t *_panel_config = (esp_lcd_rgb_panel_config_t *)heap_caps_calloc(1, sizeof(esp_lcd_rgb_panel_config_t), MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);
_panel_config->clk_src = LCD_CLK_SRC_PLL160M;
_panel_config->timings.pclk_hz = (_prefer_speed == GFX_NOT_DEFINED) ? _speed : _prefer_speed;
_panel_config->timings.h_res = w;
_panel_config->timings.v_res = h;
// The following parameters should refer to LCD spec
_panel_config->timings.hsync_pulse_width = _hsync_pulse_width;
_panel_config->timings.hsync_back_porch = _hsync_back_porch;
_panel_config->timings.hsync_front_porch = _hsync_front_porch;
_panel_config->timings.vsync_pulse_width = _vsync_pulse_width;
_panel_config->timings.vsync_back_porch = _vsync_back_porch;
_panel_config->timings.vsync_front_porch = _vsync_front_porch;
_panel_config->timings.flags.hsync_idle_low = (_hsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.vsync_idle_low = (_vsync_polarity == 0) ? 1 : 0;
_panel_config->timings.flags.de_idle_high = 0;
_panel_config->timings.flags.pclk_active_neg = _pclk_active_neg;
_panel_config->timings.flags.pclk_idle_high = 0;
_panel_config->data_width = 16; // RGB565 in parallel mode, thus 16bit in width
_panel_config->sram_trans_align = 8;
_panel_config->psram_trans_align = 64;
_panel_config->hsync_gpio_num = _hsync;
_panel_config->vsync_gpio_num = _vsync;
_panel_config->de_gpio_num = _de;
_panel_config->pclk_gpio_num = _pclk;
if (_useBigEndian)
{
_panel_config->data_gpio_nums[0] = _g3;
_panel_config->data_gpio_nums[1] = _g4;
_panel_config->data_gpio_nums[2] = _g5;
_panel_config->data_gpio_nums[3] = _r0;
_panel_config->data_gpio_nums[4] = _r1;
_panel_config->data_gpio_nums[5] = _r2;
_panel_config->data_gpio_nums[6] = _r3;
_panel_config->data_gpio_nums[7] = _r4;
_panel_config->data_gpio_nums[8] = _b0;
_panel_config->data_gpio_nums[9] = _b1;
_panel_config->data_gpio_nums[10] = _b2;
_panel_config->data_gpio_nums[11] = _b3;
_panel_config->data_gpio_nums[12] = _b4;
_panel_config->data_gpio_nums[13] = _g0;
_panel_config->data_gpio_nums[14] = _g1;
_panel_config->data_gpio_nums[15] = _g2;
}
else
{
_panel_config->data_gpio_nums[0] = _b0;
_panel_config->data_gpio_nums[1] = _b1;
_panel_config->data_gpio_nums[2] = _b2;
_panel_config->data_gpio_nums[3] = _b3;
_panel_config->data_gpio_nums[4] = _b4;
_panel_config->data_gpio_nums[5] = _g0;
_panel_config->data_gpio_nums[6] = _g1;
_panel_config->data_gpio_nums[7] = _g2;
_panel_config->data_gpio_nums[8] = _g3;
_panel_config->data_gpio_nums[9] = _g4;
_panel_config->data_gpio_nums[10] = _g5;
_panel_config->data_gpio_nums[11] = _r0;
_panel_config->data_gpio_nums[12] = _r1;
_panel_config->data_gpio_nums[13] = _r2;
_panel_config->data_gpio_nums[14] = _r3;
_panel_config->data_gpio_nums[15] = _r4;
}
_panel_config->disp_gpio_num = GPIO_NUM_NC;
_panel_config->flags.disp_active_low = 0;
_panel_config->flags.relax_on_idle = 0;
_panel_config->flags.fb_in_psram = 1; // allocate frame buffer in PSRAM
ESP_ERROR_CHECK(esp_lcd_new_rgb_panel(_panel_config, &_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_reset(_panel_handle));
ESP_ERROR_CHECK(esp_lcd_panel_init(_panel_handle));
uint16_t color = random(0xffff);
ESP_ERROR_CHECK(_panel_handle->draw_bitmap(_panel_handle, 0, 0, 1, 1, &color));
_rgb_panel = __containerof(_panel_handle, esp_rgb_panel_t, base);
return (uint16_t *)_rgb_panel->fb;
}
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -0,0 +1,102 @@
#ifdef HASP_USE_ARDUINOGFX
#include "Arduino.h"
#include "Arduino_DataBus.h"
#endif
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)
#include "databus/Arduino_ESP32RGBPanel.h" // struct esp_rgb_panel_t
#ifndef _ARDUINO_RGBPANEL_MOD_H_
#define _ARDUINO_RGBPANEL_MOD_H_
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_rgb.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lcd_panel_interface.h"
#include "esp_private/gdma.h"
#include "esp_pm.h"
#include "hal/dma_types.h"
#include "hal/lcd_hal.h"
#include "hal/lcd_ll.h"
#include "esp32s3/rom/cache.h"
// This function is located in ROM (also see esp_rom/${target}/ld/${target}.rom.ld)
extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size);
// extract from esp-idf esp_lcd_rgb_panel.c
/*struct esp_rgb_panel_t
{
esp_lcd_panel_t base; // Base class of generic lcd panel
int panel_id; // LCD panel ID
lcd_hal_context_t hal; // Hal layer object
size_t data_width; // Number of data lines (e.g. for RGB565, the data width is 16)
size_t sram_trans_align; // Alignment for framebuffer that allocated in SRAM
size_t psram_trans_align; // Alignment for framebuffer that allocated in PSRAM
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
intr_handle_t intr; // LCD peripheral interrupt handle
esp_pm_lock_handle_t pm_lock; // Power management lock
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
uint8_t *fb; // Frame buffer
size_t fb_size; // Size of frame buffer
int data_gpio_nums[SOC_LCD_RGB_DATA_WIDTH]; // GPIOs used for data lines, we keep these GPIOs for action like "invert_color"
size_t resolution_hz; // Peripheral clock resolution
esp_lcd_rgb_timing_t timings; // RGB timing parameters (e.g. pclk, sync pulse, porch width)
gdma_channel_handle_t dma_chan; // DMA channel handle
esp_lcd_rgb_panel_frame_trans_done_cb_t on_frame_trans_done; // Callback, invoked after frame trans done
void *user_ctx; // Reserved user's data of callback functions
int x_gap; // Extra gap in x coordinate, it's used when calculate the flush window
int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window
struct
{
unsigned int disp_en_level : 1; // The level which can turn on the screen by `disp_gpio_num`
unsigned int stream_mode : 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done
unsigned int fb_in_psram : 1; // Whether the frame buffer is in PSRAM
} flags;
dma_descriptor_t dma_nodes[]; // DMA descriptor pool of size `num_dma_nodes`
};*/
class Arduino_RGBPanel_Mod
{
public:
Arduino_RGBPanel_Mod(
int8_t de, int8_t vsync, int8_t hsync, int8_t pclk,
int8_t r0, int8_t r1, int8_t r2, int8_t r3, int8_t r4,
int8_t g0, int8_t g1, int8_t g2, int8_t g3, int8_t g4, int8_t g5,
int8_t b0, int8_t b1, int8_t b2, int8_t b3, int8_t b4,
uint16_t hsync_polarity, uint16_t hsync_front_porch, uint16_t hsync_pulse_width, uint16_t hsync_back_porch,
uint16_t vsync_polarity, uint16_t vsync_front_porch, uint16_t vsync_pulse_width, uint16_t vsync_back_porch,
uint16_t pclk_active_neg = 0, int32_t prefer_speed = GFX_NOT_DEFINED, bool useBigEndian = false);
void begin(int32_t speed = GFX_NOT_DEFINED);
uint16_t *getFrameBuffer(int16_t w, int16_t h);
esp_lcd_panel_handle_t _panel_handle = NULL;
protected:
private:
int32_t _speed;
int8_t _de, _vsync, _hsync, _pclk;
int8_t _r0, _r1, _r2, _r3, _r4;
int8_t _g0, _g1, _g2, _g3, _g4, _g5;
int8_t _b0, _b1, _b2, _b3, _b4;
uint16_t _hsync_polarity;
uint16_t _hsync_front_porch;
uint16_t _hsync_pulse_width;
uint16_t _hsync_back_porch;
uint16_t _vsync_polarity;
uint16_t _vsync_front_porch;
uint16_t _vsync_pulse_width;
uint16_t _vsync_back_porch;
uint16_t _pclk_active_neg;
int32_t _prefer_speed;
bool _useBigEndian;
esp_rgb_panel_t *_rgb_panel;
};
#endif // _ARDUINO_ESP32RGBPANEL_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -1,35 +1,61 @@
#include "Arduino_ESP32RGBPanel_mod.h" #include "Arduino_RGB_Display_mod.h"
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) && defined(HASP_USE_ARDUINOGFX) #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) && defined(HASP_USE_ARDUINOGFX)
#include "Arduino_GFX.h" #include "Arduino_GFX.h"
#include "Arduino_DataBus.h" #include "Arduino_DataBus.h"
#include "Arduino_RPi_DPI_RGBPanel_mod.h" #include "Arduino_RGB_Display_mod.h"
Arduino_RGBPanel_Mod::Arduino_RGBPanel_Mod(Arduino_ESP32RGBPanel_Mod* bus, int16_t w, uint16_t hsync_polarity, Arduino_RGB_Display_Mod::Arduino_RGB_Display_Mod(int16_t w, int16_t h, Arduino_RGBPanel_Mod* rgbpanel, uint8_t r,
uint16_t hsync_front_porch, uint16_t hsync_pulse_width, bool auto_flush, Arduino_DataBus* bus, int8_t rst,
uint16_t hsync_back_porch, int16_t h, uint16_t vsync_polarity, const uint8_t* init_operations, size_t init_operations_len)
uint16_t vsync_front_porch, uint16_t vsync_pulse_width, : Arduino_GFX(w, h), _rgbpanel(rgbpanel), _auto_flush(auto_flush), _bus(bus), _rst(rst),
uint16_t vsync_back_porch, uint16_t pclk_active_neg, _init_operations(init_operations), _init_operations_len(init_operations_len)
int32_t prefer_speed, bool auto_flush)
: Arduino_GFX(w, h), _bus(bus), _hsync_polarity(hsync_polarity), _hsync_front_porch(hsync_front_porch),
_hsync_pulse_width(hsync_pulse_width), _hsync_back_porch(hsync_back_porch), _vsync_polarity(vsync_polarity),
_vsync_front_porch(vsync_front_porch), _vsync_pulse_width(vsync_pulse_width), _vsync_back_porch(vsync_back_porch),
_pclk_active_neg(pclk_active_neg), _prefer_speed(prefer_speed), _auto_flush(auto_flush)
{ {
_framebuffer_size = w * h * 2; _framebuffer_size = w * h * 2;
_rotation = r;
} }
void Arduino_RGBPanel_Mod::begin(int32_t speed) bool Arduino_RGB_Display_Mod::begin(int32_t speed)
{ {
_bus->begin(speed); _rgbpanel->begin(speed);
_framebuffer = _bus->getFrameBuffer(_width, _height, _hsync_pulse_width, _hsync_back_porch, _hsync_front_porch, if(_bus) {
_hsync_polarity, _vsync_pulse_width, _vsync_back_porch, _vsync_front_porch, _bus->begin();
_vsync_polarity, _pclk_active_neg, _prefer_speed);
} }
void Arduino_RGBPanel_Mod::writePixelPreclipped(int16_t x, int16_t y, uint16_t color) if(_rst != GFX_NOT_DEFINED) {
pinMode(_rst, OUTPUT);
digitalWrite(_rst, HIGH);
delay(100);
digitalWrite(_rst, LOW);
delay(120);
digitalWrite(_rst, HIGH);
delay(120);
} else {
if(_bus) {
// Software Rest
_bus->sendCommand(0x01);
delay(120);
}
}
if(_bus) {
if(_init_operations_len > 0) {
_bus->batchOperation((uint8_t*)_init_operations, _init_operations_len);
}
}
_framebuffer = _rgbpanel->getFrameBuffer(WIDTH, HEIGHT);
if(!_framebuffer) {
return false;
}
return true;
}
void Arduino_RGB_Display_Mod::writePixelPreclipped(int16_t x, int16_t y, uint16_t color)
{ {
uint16_t* fb = _framebuffer; uint16_t* fb = _framebuffer;
fb += (int32_t)y * _width; fb += (int32_t)y * _width;
@ -40,7 +66,7 @@ void Arduino_RGBPanel_Mod::writePixelPreclipped(int16_t x, int16_t y, uint16_t c
} }
} }
void Arduino_RGBPanel_Mod::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) void Arduino_RGB_Display_Mod::writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color)
{ {
if(_ordered_in_range(x, 0, _max_x) && h) { // X on screen, nonzero height if(_ordered_in_range(x, 0, _max_x) && h) { // X on screen, nonzero height
if(h < 0) { // If negative height... if(h < 0) { // If negative height...
@ -77,7 +103,7 @@ void Arduino_RGBPanel_Mod::writeFastVLine(int16_t x, int16_t y, int16_t h, uint1
} }
} }
void Arduino_RGBPanel_Mod::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) void Arduino_RGB_Display_Mod::writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color)
{ {
if(_ordered_in_range(y, 0, _max_y) && w) { // Y on screen, nonzero width if(_ordered_in_range(y, 0, _max_y) && w) { // Y on screen, nonzero width
if(w < 0) { // If negative width... if(w < 0) { // If negative width...
@ -110,7 +136,7 @@ void Arduino_RGBPanel_Mod::writeFastHLine(int16_t x, int16_t y, int16_t w, uint1
} }
} }
void Arduino_RGBPanel_Mod::writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) void Arduino_RGB_Display_Mod::writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
{ {
uint16_t* row = _framebuffer; uint16_t* row = _framebuffer;
row += y * _width; row += y * _width;
@ -127,19 +153,20 @@ void Arduino_RGBPanel_Mod::writeFillRectPreclipped(int16_t x, int16_t y, int16_t
} }
} }
void Arduino_RGBPanel_Mod::setRotation(uint8_t r) void Arduino_RGB_Display_Mod::setRotation(uint8_t r)
{ {
esp_err_t err = esp_lcd_panel_swap_xy(_bus->_panel_handle, r & 1); esp_err_t err = esp_lcd_panel_swap_xy(_rgbpanel->_panel_handle, r & 1);
err = esp_lcd_panel_mirror(_bus->_panel_handle, r & 4, r & 2); err = esp_lcd_panel_mirror(_rgbpanel->_panel_handle, r & 4, r & 2);
}
void Arduino_RGBPanel_Mod::invertDisplay(bool i)
{
esp_err_t err = esp_lcd_panel_invert_color(_bus->_panel_handle, i);
} }
void Arduino_RGBPanel_Mod::draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t* bitmap, int16_t w, int16_t h) void Arduino_RGB_Display_Mod::invertDisplay(bool i)
{ {
esp_err_t err = esp_lcd_panel_draw_bitmap(_bus->_panel_handle, x, y, x + w, y + h, bitmap); esp_err_t err = esp_lcd_panel_invert_color(_rgbpanel->_panel_handle, i);
}
void Arduino_RGB_Display_Mod::draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t* bitmap, int16_t w, int16_t h)
{
esp_err_t err = esp_lcd_panel_draw_bitmap(_rgbpanel->_panel_handle, x, y, x + w, y + h, bitmap);
return; return;
if(((x + w - 1) < 0) || // Outside left if(((x + w - 1) < 0) || // Outside left
@ -201,7 +228,7 @@ void Arduino_RGBPanel_Mod::draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t* bi
} }
} }
void Arduino_RGBPanel_Mod::draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t* bitmap, int16_t w, int16_t h) void Arduino_RGB_Display_Mod::draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t* bitmap, int16_t w, int16_t h)
{ {
if(((x + w - 1) < 0) || // Outside left if(((x + w - 1) < 0) || // Outside left
((y + h - 1) < 0) || // Outside top ((y + h - 1) < 0) || // Outside top
@ -248,14 +275,14 @@ void Arduino_RGBPanel_Mod::draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t*
} }
} }
void Arduino_RGBPanel_Mod::flush(void) void Arduino_RGB_Display_Mod::flush(void)
{ {
if(!_auto_flush) { if(!_auto_flush) {
Cache_WriteBack_Addr((uint32_t)_framebuffer, _framebuffer_size); Cache_WriteBack_Addr((uint32_t)_framebuffer, _framebuffer_size);
} }
} }
uint16_t* Arduino_RGBPanel_Mod::getFramebuffer() uint16_t* Arduino_RGB_Display_Mod::getFramebuffer()
{ {
return _framebuffer; return _framebuffer;
} }

View File

@ -0,0 +1,49 @@
#ifdef HASP_USE_ARDUINOGFX
#include "Arduino.h"
#include "Arduino_DataBus.h"
#endif
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) && defined(HASP_USE_ARDUINOGFX)
#ifndef _ARDUINO_RGB_DISPLAY_MOD_H_
#define _ARDUINO_RGB_DISPLAY_MOD_H_
#include "Arduino_GFX.h"
#include "Arduino_RGBPanel_mod.h"
class Arduino_RGB_Display_Mod : public Arduino_GFX{
public:
Arduino_RGB_Display_Mod(
int16_t w, int16_t h, Arduino_RGBPanel_Mod *rgbpanel, uint8_t r = 0, bool auto_flush = true,
Arduino_DataBus *bus = NULL, int8_t rst = GFX_NOT_DEFINED, const uint8_t *init_operations = NULL, size_t init_operations_len = GFX_NOT_DEFINED);
bool begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void flush(void) override;
void setRotation(uint8_t r);
void invertDisplay(bool i);
uint16_t *getFramebuffer();
Arduino_DataBus *_bus;
Arduino_RGBPanel_Mod *_rgbpanel;
protected:
uint16_t *_framebuffer;
size_t _framebuffer_size;
bool _auto_flush;
int8_t _rst;
const uint8_t *_init_operations;
size_t _init_operations_len;
private:
};
#endif // _ARDUINO_RGB_DISPLAY_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -1,61 +0,0 @@
#ifdef HASP_USE_ARDUINOGFX
#include "Arduino.h"
#include "Arduino_DataBus.h"
#endif
#if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3) && defined(HASP_USE_ARDUINOGFX)
#include "Arduino_DataBus.h"
#ifndef _ARDUINO_RPI_DPI_RGBPANEL_MOD_H_
#define _ARDUINO_RPI_DPI_RGBPANEL_MOD_H_
#include "Arduino_GFX.h"
#include "Arduino_ESP32RGBPanel_mod.h"
class Arduino_RGBPanel_Mod : public Arduino_GFX
{
public:
Arduino_RGBPanel_Mod(
Arduino_ESP32RGBPanel_Mod *bus,
int16_t w, uint16_t hsync_polarity, uint16_t hsync_front_porch, uint16_t hsync_pulse_width, uint16_t hsync_back_porch,
int16_t h, uint16_t vsync_polarity, uint16_t vsync_front_porch, uint16_t vsync_pulse_width, uint16_t vsync_back_porch,
uint16_t pclk_active_neg = 0, int32_t prefer_speed = GFX_NOT_DEFINED, bool auto_flush = true);
void begin(int32_t speed = GFX_NOT_DEFINED) override;
void writePixelPreclipped(int16_t x, int16_t y, uint16_t color) override;
void writeFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) override;
void writeFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) override;
void writeFillRectPreclipped(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override;
void draw16bitRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void draw16bitBeRGBBitmap(int16_t x, int16_t y, uint16_t *bitmap, int16_t w, int16_t h) override;
void flush(void) override;
void setRotation(uint8_t r);
void invertDisplay(bool i);
uint16_t *getFramebuffer();
Arduino_ESP32RGBPanel_Mod *_bus;
protected:
uint16_t *_framebuffer;
size_t _framebuffer_size;
uint16_t _hsync_polarity;
uint16_t _hsync_front_porch;
uint16_t _hsync_pulse_width;
uint16_t _hsync_back_porch;
uint16_t _vsync_polarity;
uint16_t _vsync_front_porch;
uint16_t _vsync_pulse_width;
uint16_t _vsync_back_porch;
uint16_t _pclk_active_neg;
int32_t _prefer_speed;
bool _auto_flush;
private:
};
#endif // _ARDUINO_RPI_DPI_RGBPANEL_H_
#endif // #if defined(ESP32) && (CONFIG_IDF_TARGET_ESP32S3)

View File

@ -5,8 +5,9 @@
#include "tft_driver_arduinogfx.h" #include "tft_driver_arduinogfx.h"
#include <Preferences.h> #include <Preferences.h>
#include "Arduino_RPi_DPI_RGBPanel_mod.h" #include "Arduino_RGBPanel_mod.h"
#include "Arduino_ESP32RGBPanel_mod.h" #include "Arduino_RGB_Display_mod.h"
namespace dev { namespace dev {
void tftPinInfo(const __FlashStringHelper* pinfunction, int8_t pin) void tftPinInfo(const __FlashStringHelper* pinfunction, int8_t pin)
@ -44,15 +45,25 @@ void ArduinoGfx::init(int w, int h)
480 /* height */, st7701_type1_init_operations, 480 /* height */, st7701_type1_init_operations,
sizeof(st7701_type1_init_operations), true /* BGR */); sizeof(st7701_type1_init_operations), true /* BGR */);
#elif 1 #elif 1
Arduino_ESP32RGBPanel_Mod* bus = new Arduino_ESP32RGBPanel_Mod( /* Reset is not implemented in the panel */
GFX_NOT_DEFINED /* CS */, GFX_NOT_DEFINED /* SCK */, GFX_NOT_DEFINED /* SDA */, TFT_DE, TFT_VSYNC, TFT_HSYNC, if(TFT_RST != GFX_NOT_DEFINED) {
TFT_PCLK, TFT_R0, TFT_R1, TFT_R2, TFT_R3, TFT_R4, TFT_G0, TFT_G1, TFT_G2, TFT_G3, TFT_G4, TFT_G5, TFT_B0, pinMode(TFT_RST, OUTPUT);
TFT_B1, TFT_B2, TFT_B3, TFT_B4); digitalWrite(TFT_RST, HIGH);
delay(100);
digitalWrite(TFT_RST, LOW);
delay(120);
digitalWrite(TFT_RST, HIGH);
delay(120);
}
tft = new Arduino_RGBPanel_Mod(bus, TFT_WIDTH, TFT_HSYNC_POLARITY, TFT_HSYNC_FRONT_PORCH, TFT_HSYNC_PULSE_WIDTH, Arduino_RGBPanel_Mod* bus = new Arduino_RGBPanel_Mod(
TFT_HSYNC_BACK_PORCH, TFT_HEIGHT, TFT_VSYNC_POLARITY, TFT_VSYNC_FRONT_PORCH, TFT_DE, TFT_VSYNC, TFT_HSYNC, TFT_PCLK, TFT_R0, TFT_R1, TFT_R2, TFT_R3, TFT_R4, TFT_G0, TFT_G1, TFT_G2, TFT_G3,
TFT_VSYNC_PULSE_WIDTH, TFT_VSYNC_BACK_PORCH, TFT_PCLK_ACTIVE_NEG, TFT_PREFER_SPEED, TFT_G4, TFT_G5, TFT_B0, TFT_B1, TFT_B2, TFT_B3, TFT_B4, TFT_HSYNC_POLARITY, TFT_HSYNC_FRONT_PORCH,
TFT_AUTO_FLUSH); TFT_HSYNC_PULSE_WIDTH, TFT_HSYNC_BACK_PORCH, TFT_VSYNC_POLARITY, TFT_VSYNC_FRONT_PORCH, TFT_VSYNC_PULSE_WIDTH,
TFT_VSYNC_BACK_PORCH, TFT_PCLK_ACTIVE_NEG, TFT_PREFER_SPEED);
Arduino_RGB_Display_Mod* gfx = new Arduino_RGB_Display_Mod(TFT_WIDTH, TFT_HEIGHT, bus);
tft = gfx;
// fb = ((Arduino_RGBPanel_Mod*)tft)->getFramebuffer(); // fb = ((Arduino_RGBPanel_Mod*)tft)->getFramebuffer();
#endif #endif

View File

@ -9,6 +9,8 @@
#include "lvgl.h" #include "lvgl.h"
#include <Arduino_GFX_Library.h> #include <Arduino_GFX_Library.h>
#include "Arduino_RGBPanel_mod.h"
#include "Arduino_RGB_Display_mod.h"
#include "tft_driver.h" #include "tft_driver.h"
#include "hal/hasp_hal.h" #include "hal/hasp_hal.h"