Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion extras/board_spec/test/board_spec.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2329,7 +2329,7 @@ test("Tab5 touch identities select the three DSI panels", async () => {
const tab5SetupSource = await fs.readFile(path.join(root, "../../src/board_detect/m5/esp32p4/tab5_setup.inl"), "utf8");
assert.match(tab5SetupSource, /tab5_st7121_lane_mbps = 900/);
assert.match(tab5SetupSource, /hit_st7121 \? tab5_st7121_lane_mbps : specs::tab5::bus_lane_mbps/);
assert.match(tab5SetupSource, /fw_version == 1[\s\S]*?hit_st7121 = true[\s\S]*?fw_version == 3[\s\S]*?hit_st7123 = true/);
assert.match(tab5SetupSource, /hit_st7121 = result.prepared & tab5_detail::touch_st7121[\s\S]*?hit_st7123 = result.prepared & tab5_detail::touch_st7123/);
assert.match(tab5SetupSource, /if \(!read_st_touch_fw && !found_gt911\)[\s\S]*?delay\(80\)[\s\S]*?i < 3 && !hit_ili9881[\s\S]*?id\[0\] == 0x98 && id\[1\] == 0x81/);
assert.match(tab5SetupSource, /if \(found_gt911 \|\| hit_ili9881\)[\s\S]*?Panel_ILI9881C/);
});
Expand Down
29 changes: 22 additions & 7 deletions src/M5GFX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#include "lgfx/v1/touch/Touch_CSTxxx.hpp"
#include "lgfx/v1/touch/Touch_FT5x06.hpp"
#include "lgfx/v1/touch/Touch_GT911.hpp"
#if defined (CONFIG_IDF_TARGET_ESP32P4)
#include "lgfx/v1/platforms/esp32p4/Touch_ST7123.hpp"
#endif

#include "board_detect/m5/setup_sentinels.hpp"

Expand Down Expand Up @@ -69,7 +72,6 @@
#include "lgfx/v1/platforms/esp32p4/Panel_ST7102.hpp"
#include "lgfx/v1/platforms/esp32p4/Panel_ST7121.hpp"
#include "lgfx/v1/platforms/esp32p4/Panel_ST7123.hpp"
#include "lgfx/v1/platforms/esp32p4/Touch_ST7123.hpp"

#elif defined ( CONFIG_IDF_TARGET_ESP32S3 )

Expand Down Expand Up @@ -138,11 +140,12 @@ namespace m5gfx
#if defined (CONFIG_IDF_TARGET_ESP32P4)
struct Light_M5CoreP4X : public lgfx::ILight
{
Light_M5CoreP4X(int port, std::uint8_t addr, std::uint32_t freq)
: _port(port), _addr(addr), _freq(freq) {}
Light_M5CoreP4X(int port, int sda, int scl, std::uint8_t addr, std::uint32_t freq)
: _port(port), _sda(sda), _scl(scl), _addr(addr), _freq(freq) {}

bool init(uint8_t brightness) override
{
lgfx::i2c::init(_port, _sda, _scl);
static constexpr uint16_t pwm_freq = 1000;
const uint8_t freq_data[] = {
0x25, static_cast<uint8_t>(pwm_freq), static_cast<uint8_t>(pwm_freq >> 8)
Expand All @@ -163,6 +166,8 @@ namespace m5gfx
}
private:
int _port;
int _sda;
int _scl;
std::uint8_t _addr;
std::uint32_t _freq;
};
Expand Down Expand Up @@ -237,6 +242,7 @@ namespace m5gfx
{
bool init(std::uint8_t brightness) override
{
lgfx::i2c::init(axp_i2c_port, axp_i2c_sda, axp_i2c_scl);
setBrightness(brightness);
return true;
}
Expand All @@ -261,6 +267,7 @@ namespace m5gfx
{
bool init(std::uint8_t brightness) override
{
lgfx::i2c::init(axp_i2c_port, axp_i2c_sda, axp_i2c_scl);
setBrightness(brightness);
return true;
}
Expand All @@ -286,6 +293,7 @@ namespace m5gfx
{
bool init(std::uint8_t brightness) override
{
lgfx::i2c::init(axp_i2c_port, axp_i2c_sda, axp_i2c_scl);
setBrightness(brightness);
return true;
}
Expand Down Expand Up @@ -478,6 +486,7 @@ namespace m5gfx
{
bool init(uint8_t brightness) override
{
lgfx::i2c::init(i2c_port, i2c_sda, i2c_scl);
setBrightness(brightness);
return true;
}
Expand Down Expand Up @@ -700,12 +709,13 @@ namespace m5gfx

struct Light_M5ToughC5 : public lgfx::ILight
{
Light_M5ToughC5(int_fast16_t port, std::uint8_t addr, std::uint32_t freq)
: _port(port), _addr(addr), _freq(freq) {}
Light_M5ToughC5(int_fast16_t port, int sda, int scl, std::uint8_t addr, std::uint32_t freq)
: _port(port), _sda(sda), _scl(scl), _addr(addr), _freq(freq) {}
// LCD backlight = M5IOE1 PIN10, driven by the expander's PWM channel 4.
// Registers: 0x21/0x22 = PWM4 duty (12bit, H[7]=enable), 0x25/0x26 = shared PWM frequency (Hz).
bool init(uint8_t brightness) override
{
lgfx::i2c::init(_port, _sda, _scl);
static constexpr uint8_t freq_1khz[] = { 0x25, 0xE8, 0x03 };
lgfx::i2c::transactionWrite(_port, _addr, freq_1khz, sizeof(freq_1khz), _freq);
lgfx::i2c::bitOn(_port, _addr, 0x04, 0x02, _freq); // PIN10 output mode
Expand All @@ -728,6 +738,8 @@ namespace m5gfx
}
private:
int_fast16_t _port;
int _sda;
int _scl;
std::uint8_t _addr;
std::uint32_t _freq;
};
Expand All @@ -736,11 +748,12 @@ namespace m5gfx

struct Light_ArduinoNessoN1 : public lgfx::ILight
{
Light_ArduinoNessoN1(int_fast16_t port, std::uint8_t addr, std::uint32_t freq)
: _port(port), _addr(addr), _freq(freq) {}
Light_ArduinoNessoN1(int_fast16_t port, int sda, int scl, std::uint8_t addr, std::uint32_t freq)
: _port(port), _sda(sda), _scl(scl), _addr(addr), _freq(freq) {}

bool init(uint8_t brightness) override
{
lgfx::i2c::init(_port, _sda, _scl);
setBrightness(brightness);
return true;
}
Expand All @@ -756,6 +769,8 @@ namespace m5gfx

private:
int_fast16_t _port;
int _sda;
int _scl;
std::uint8_t _addr;
std::uint32_t _freq;
};
Expand Down
27 changes: 5 additions & 22 deletions src/board_detect/board_detect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
#include <cstdint>
#include <initializer_list>

#if defined (M5GFX_BOARD_DETECT_HOST_HAL)
#include M5GFX_BOARD_DETECT_HOST_HAL
#else
#include "../lgfx/v1/platforms/esp32/common.hpp"
#endif
#include "detect_io.hpp"
#include "dedicated_release_probe.hpp"
#include "ops.hpp"
#include "detect_types.hpp"
Expand Down Expand Up @@ -92,24 +88,12 @@ namespace board_detect
void rollback();

private:
lgfx::gpio::pin_backup_t saved_[max_detection_pins];
io::pin_state_t saved_[max_detection_pins];
std::uint8_t count_ = 0;
};

class detection_bus_journal_t
{
public:
void opened_i2c(int port);
void rollback();
void commit();

private:
std::int8_t i2c_ports_[2] = { -1, -1 };
std::uint8_t i2c_count_ = 0;
};

// Capture releases LP pad ownership after saving GPIO state.
// Rollback restores GPIO and releases journaled buses, but deliberately leaves
// Rollback restores GPIO, but deliberately leaves
// LP ownership released: stale LP routing would hide the pad behind a controller-held line.
// PMIC register writes are not restored.
class detection_transaction_t
Expand All @@ -127,11 +111,9 @@ namespace board_detect
void restore_start(const std::int8_t (&pins)[N]) { restore_start(pins, N); }
void rollback();
void commit();
detection_bus_journal_t& buses() { return buses_; }

private:
detection_gpio_snapshot_t gpio_;
detection_bus_journal_t buses_;
bool valid_ = false;
bool committed_ = false;
};
Expand Down Expand Up @@ -229,7 +211,8 @@ namespace board_detect
struct i2c_desc_t
{
// PMIC power/reset descriptions require valid SDA/SCL even when hw_port
// is -1; hw_port only controls whether the bus remains open after prepare.
// is -1. hw_port tells consumers which hardware port to open themselves;
// detection uses only software I2C and does not initialize hardware ports.
std::int8_t sda;
std::int8_t scl;
std::int8_t hw_port;
Expand Down
108 changes: 0 additions & 108 deletions src/board_detect/board_detect.inl
Original file line number Diff line number Diff line change
Expand Up @@ -10,119 +10,11 @@

#include <cstdio>
#include <cstring>
#include <driver/gpio.h>
#include <soc/gpio_reg.h>
#include <esp_log.h>
#if defined (CONFIG_IDF_TARGET_ESP32S3) \
&& __has_include(<driver/dedic_gpio.h>) \
&& (__has_include(<hal/dedic_gpio_cpu_ll.h>) || __has_include(<hal/cpu_ll.h>)) \
&& (__has_include(<esp_private/esp_clk.h>) || __has_include(<esp_clk.h>))
#define M5GFX_HAS_S3_DEDICATED_GPIO_RELEASE_PROBE
#include <driver/dedic_gpio.h>
#include <esp_cpu.h>
#include <esp_idf_version.h>
#if __has_include(<esp_private/esp_clk.h>)
#include <esp_private/esp_clk.h>
#else
#include <esp_clk.h>
#endif
#include <freertos/FreeRTOS.h>
#if __has_include(<hal/dedic_gpio_cpu_ll.h>)
#include <hal/dedic_gpio_cpu_ll.h>
#else
// IDF 4.4 exposes the same S3 instructions through cpu_ll.h and reports
// allocated channels as masks rather than offsets.
#define M5GFX_S3_DEDICATED_GPIO_LEGACY_CPU_LL
#include <hal/cpu_ll.h>
#endif
#include <hal/gpio_ll.h>
#include <soc/gpio_periph.h>
#include <soc/gpio_reg.h>
#include <soc/io_mux_reg.h>
#include <soc/system_reg.h>
#endif

namespace m5gfx
{
namespace board_detect
{
#if defined (M5GFX_HAS_S3_DEDICATED_GPIO_RELEASE_PROBE)
static inline std::uint32_t dedicated_release_read_in()
{
#if defined (M5GFX_S3_DEDICATED_GPIO_LEGACY_CPU_LL)
return cpu_ll_read_dedic_gpio_in();
#else
return dedic_gpio_cpu_ll_read_in();
#endif
}

static inline void dedicated_release_write_mask(std::uint32_t mask, std::uint32_t value)
{
#if defined (M5GFX_S3_DEDICATED_GPIO_LEGACY_CPU_LL)
cpu_ll_write_dedic_gpio_mask(mask, value);
#else
dedic_gpio_cpu_ll_write_mask(mask, value);
#endif
}

static void dedicated_release_channel_masks(
dedic_gpio_bundle_handle_t bundle, std::uint8_t pin_count,
std::uint32_t* in_mask, std::uint32_t* out_mask,
esp_err_t* in_error, esp_err_t* out_error)
{
#if defined (M5GFX_S3_DEDICATED_GPIO_LEGACY_CPU_LL)
*in_error = dedic_gpio_get_in_mask(bundle, in_mask);
*out_error = dedic_gpio_get_out_mask(bundle, out_mask);
#else
std::uint32_t in_offset = 0;
std::uint32_t out_offset = 0;
*in_error = dedic_gpio_get_in_offset(bundle, &in_offset);
*out_error = dedic_gpio_get_out_offset(bundle, &out_offset);
const std::uint32_t channel_mask = (1u << pin_count) - 1u;
*in_mask = channel_mask << in_offset;
*out_mask = channel_mask << out_offset;
#endif
}

static inline int dedicated_release_core_id()
{
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
return esp_cpu_get_core_id();
#else
return xPortGetCoreID();
#endif
}

static inline std::uint32_t dedicated_release_cycle_count()
{
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
return esp_cpu_get_cycle_count();
#else
return esp_cpu_get_ccount();
#endif
}

static inline int dedicated_release_task_core()
{
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0)
return xTaskGetCoreID(nullptr);
#else
return xTaskGetAffinity(nullptr);
#endif
}

static bool delete_dedicated_release_bundle(dedic_gpio_bundle_handle_t bundle)
{
const esp_err_t error = dedic_gpio_del_bundle(bundle);
if (error != ESP_OK)
{
ESP_LOGW("M5GFX", "[Autodetect] dedicated GPIO bundle cleanup failed (%d)", int(error));
return false;
}
return true;
}
#endif

// Call after family-specific evidence gates; a hint is eligible only while
// that member remains possible. Defaults may be absent for open families.
// Only some chips' detectors use it.
Expand Down
Loading
Loading