
#include "roo_display/hal/config.h"

#if defined(ESP_PLATFORM) && CONFIG_IDF_TARGET_ESP32S3

#if defined(ARDUINO)
#include "roo_io/fs/esp32/arduino/sdmmc.h"
#else
#include "roo_io/fs/esp32/esp-idf/sdmmc.h"
#endif

#include "roo_display/products/makerfabs/esp32s3_parallel_ips_capacitive.h"

namespace roo_display::products::makerfabs {

namespace {
constexpr esp32s3_dma::Config kTftConfig800x480 = {.width = 800,
                                                   .height = 480,
                                                   .de = 40,
                                                   .hsync = 39,
                                                   .vsync = 41,
                                                   .pclk = 42,

                                                   .hsync_pulse_width = 4,
                                                   .hsync_back_porch = 16,
                                                   .hsync_front_porch = 80,
                                                   .hsync_polarity = 0,
                                                   .vsync_pulse_width = 4,
                                                   .vsync_back_porch = 4,
                                                   .vsync_front_porch = 22,
                                                   .vsync_polarity = 0,
                                                   .pclk_active_neg = 1,
                                                   .prefer_speed = -1,

                                                   .r0 = 45,
                                                   .r1 = 48,
                                                   .r2 = 47,
                                                   .r3 = 21,
                                                   .r4 = 14,
                                                   .g0 = 5,
                                                   .g1 = 6,
                                                   .g2 = 7,
                                                   .g3 = 15,
                                                   .g4 = 16,
                                                   .g5 = 4,
                                                   .b0 = 8,
                                                   .b1 = 3,
                                                   .b2 = 46,
                                                   .b3 = 9,
                                                   .b4 = 1,
                                                   .bswap = false};

constexpr esp32s3_dma::Config kTftConfig1024x600 = {.width = 1024,
                                                    .height = 600,
                                                    .de = 40,
                                                    .hsync = 39,
                                                    .vsync = 41,
                                                    .pclk = 42,

                                                    .hsync_pulse_width = 4,
                                                    .hsync_back_porch = 16,
                                                    .hsync_front_porch = 80,
                                                    .hsync_polarity = 0,
                                                    .vsync_pulse_width = 4,
                                                    .vsync_back_porch = 4,
                                                    .vsync_front_porch = 22,
                                                    .vsync_polarity = 0,
                                                    .pclk_active_neg = 1,
                                                    .prefer_speed = -1,

                                                    .r0 = 45,
                                                    .r1 = 48,
                                                    .r2 = 47,
                                                    .r3 = 21,
                                                    .r4 = 14,
                                                    .g0 = 5,
                                                    .g1 = 6,
                                                    .g2 = 7,
                                                    .g3 = 15,
                                                    .g4 = 16,
                                                    .g5 = 4,
                                                    .b0 = 8,
                                                    .b1 = 3,
                                                    .b2 = 46,
                                                    .b3 = 9,
                                                    .b4 = 1,
                                                    .bswap = false};
}  // namespace

Esp32s3ParallelIpsCapacitive::Esp32s3ParallelIpsCapacitive(
    Resolution resolution, Orientation orientation, I2cMasterBusHandle i2c)
    : resolution_(resolution),
      i2c_(std::move(i2c)),
      display_(resolution_ == k800x480 ? kTftConfig800x480
                                       : kTftConfig1024x600),
      // Note: UART 'nack' errors have been observed when reset hold down time
      // is below 300ms. This startup delay isn't very painful because the
      // driver performs reset asynchronously.
      touch_(i2c_, -1, 38, 300) {
  display_.setOrientation(orientation);
}

void Esp32s3ParallelIpsCapacitive::initTransport() {
  i2c_.init(pin_sda(), pin_scl());
#if defined(ARDUINO)
  roo_io::SD_MMC.setPins(pin_sd_clk(), pin_sd_cmd(), pin_sd_d0());
#else
  roo_io::SDMMC.setPins(pin_sd_clk(), pin_sd_cmd(), pin_sd_d0());
#endif
}

roo_io::BaseEsp32VfsFilesystem& Esp32s3ParallelIpsCapacitive::sd() const {
#if defined(ARDUINO)
  return roo_io::SD_MMC;
#else
  return roo_io::SDMMC;
#endif
}

TouchCalibration Esp32s3ParallelIpsCapacitive::touch_calibration() {
  return resolution_ == k800x480
             ? TouchCalibration(0, 0, 800, 480)
             : TouchCalibration(0, 0, 1024,
                                768);  // Yes, 768 is the correct value.
}

}  // namespace roo_display::products::makerfabs

#endif  // defined(ESP_PLATFORM) && CONFIG_IDF_TARGET_ESP32S3