Skip to content

Commit

Permalink
add support M5Stack Core2 v1.1 (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
lovyan03 committed Feb 18, 2024
1 parent a7adcfa commit 0628459
Showing 1 changed file with 112 additions and 33 deletions.
145 changes: 112 additions & 33 deletions src/lgfx/v1_autodetect/LGFX_AutoDetect_ESP32_all.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ namespace lgfx

static constexpr char LIBRARY_NAME[] = "LovyanGFX";

void i2c_write_register8_array(int_fast16_t i2c_port, uint_fast8_t i2c_addr, const uint8_t* reg_data_mask, uint32_t freq)
{
while (reg_data_mask[0] != 0xFF || reg_data_mask[1] != 0xFF || reg_data_mask[2] != 0xFF)
{
lgfx::i2c::writeRegister8(i2c_port, i2c_addr, reg_data_mask[0], reg_data_mask[1], reg_data_mask[2], freq);
reg_data_mask += 3;
}
}

#if defined (CONFIG_IDF_TARGET_ESP32S3)

#if defined ( ARDUINO_ESP32_S3_BOX )
Expand Down Expand Up @@ -348,6 +357,33 @@ namespace lgfx
}
};

struct Light_M5StackCore2_AXP2101 : public lgfx::ILight
{
bool init(uint8_t brightness) override
{
setBrightness(brightness);
return true;
}

void setBrightness(uint8_t brightness) override
{
using namespace m5stack;

// BLDO1
if (brightness)
{
brightness = ((brightness + 641) >> 5);
lgfx::i2c::bitOn(axp_i2c_port, axp_i2c_addr, 0x90, 0x10, axp_i2c_freq); // BLDO1 enable
}
else
{
lgfx::i2c::bitOff(axp_i2c_port, axp_i2c_addr, 0x90, 0x10, axp_i2c_freq); // BLDO1 disable
}
// AXP192 reg 0x96 = BLO1 voltage setting (0.5v ~ 3.5v 100mv/step)
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, 0x96, brightness, 0, axp_i2c_freq);
}
};

struct Light_M5Tough : public lgfx::ILight
{
bool init(uint8_t brightness) override
Expand Down Expand Up @@ -2133,47 +2169,85 @@ namespace lgfx
using namespace m5stack;
_pin_backup_t backup[] = { axp_i2c_sda, axp_i2c_scl };
lgfx::i2c::init(axp_i2c_port, axp_i2c_sda, axp_i2c_scl);
if (lgfx::i2c::readRegister8(axp_i2c_port, axp_i2c_addr, 0x03, 400000) == 0x03) // AXP192 found

auto chk_axp = lgfx::i2c::readRegister8(axp_i2c_port, axp_i2c_addr, 0x03, 400000);
if (chk_axp.has_value())
{
_pin_level(GPIO_NUM_5, true);
// AXP192_LDO2 = LCD PWR
// AXP192_IO4 = LCD RST
// AXP192_DC3 = LCD BL (Core2)
// AXP192_LDO3 = LCD BL (Tough)
// AXP192_IO1 = TP RST (Tough)
static constexpr uint8_t reg_data[] =
{
0x28, 0xF0, 0xFF, // set LDO2 3300mv // LCD PWR
0x12, 0x04, 0xFF, // LDO2 enable
0x92, 0x00, 0xF8, // GPIO1 OpenDrain (M5Tough TOUCH)
0x95, 0x84, 0x72, // GPIO4 enable
0x96, 0x02, 0xFF, // GPIO4 HIGH (LCD RST)
0x94, 0x02, 0xFF, // GPIO1 HIGH (M5Tough TOUCH RST)
};
for (size_t i = 0; i < sizeof(reg_data); i += 3)
{
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, reg_data[i ], reg_data[i+1], reg_data[i+2], axp_i2c_freq);
uint_fast16_t axp_exists = 0;
if (chk_axp.value() == 0x03) { // AXP192 found
axp_exists = 192;
ESP_LOGD(LIBRARY_NAME, "AXP192 found");
}
if (use_reset)
else if (chk_axp.value() == 0x4A) { // AXP2101 found
axp_exists = 2101;
ESP_LOGD(LIBRARY_NAME, "AXP2101 found");
}
if (axp_exists)
{
static constexpr uint8_t reset_reg_data[] =
{
0x96, 0, 0xFD, // GPIO4 LOW (LCD RST)
0x94, 0, 0xFD, // GPIO1 LOW (M5Tough TOUCH RST)
// fore Core2 1st gen (AXP192)
// AXP192_LDO2 = LCD PWR
// AXP192_IO4 = LCD RST
// AXP192_DC3 = LCD BL (Core2)
// AXP192_LDO3 = LCD BL (Tough)
// AXP192_IO1 = TP RST (Tough)
static constexpr uint8_t reg_data_axp192_first[] = {
0x95, 0x84, 0x72, // GPIO4 enable
0x28, 0xF0, 0xFF, // set LDO2 3300mv // LCD PWR
0x12, 0x04, 0xFF, // LDO2 enable
0x92, 0x00, 0xF8, // GPIO1 OpenDrain (M5Tough TOUCH)
0xFF, 0xFF, 0xFF,
};
static constexpr uint8_t reg_data_axp192_reset[] = {
0x96, 0x00, 0xFD, // GPIO4 LOW (LCD RST)
0x94, 0x00, 0xFD, // GPIO1 LOW (M5Tough TOUCH RST)
0xFF, 0xFF, 0xFF,
};
static constexpr uint8_t reg_data_axp192_second[] = {
0x96, 0x02, 0xFF, // GPIO4 HIGH (LCD RST)
0x94, 0x02, 0xFF, // GPIO1 HIGH (M5Tough TOUCH RST)
0xFF, 0xFF, 0xFF,
};
for (size_t i = 0; i < sizeof(reset_reg_data); i += 3)
{
lgfx::i2c::writeRegister8(axp_i2c_port, axp_i2c_addr, reset_reg_data[i ], reset_reg_data[i+1], reset_reg_data[i+2], axp_i2c_freq);

// for Core2 v1.1 (AXP2101)
// ALDO2 == LCD+TOUCH RST
// ALDO3 == SPK EN
// ALDO4 == TF, TP, LCD PWR
// BLDO1 == LCD BL
// BLDO2 == Boost EN
// DLDO1 == Vibration Motor
static constexpr uint8_t reg_data_axp2101_first[] = {
0x90, 0x08, 0x7B, // ALDO4 ON / ALDO3 OFF, DLDO1 OFF
0x80, 0x05, 0xFF, // DCDC1 + DCDC3 ON
0x82, 0x12, 0x00, // DCDC1 3.3V
0x84, 0x6A, 0x00, // DCDC3 3.3V
0xFF, 0xFF, 0xFF,
};
static constexpr uint8_t reg_data_axp2101_reset[] = {
0x90, 0x00, 0xFD, // ALDO2 OFF
0xFF, 0xFF, 0xFF,
};
static constexpr uint8_t reg_data_axp2101_second[] = {
0x90, 0x02, 0xFF, // ALDO2 ON
0xFF, 0xFF, 0xFF,
};

_pin_level(GPIO_NUM_5, true);

bool isAxp192 = axp_exists == 192;

i2c_write_register8_array(axp_i2c_port, axp_i2c_addr, isAxp192 ? reg_data_axp192_first : reg_data_axp2101_first, axp_i2c_freq);
if (use_reset) {
i2c_write_register8_array(axp_i2c_port, axp_i2c_addr, isAxp192 ? reg_data_axp192_reset : reg_data_axp2101_reset, axp_i2c_freq);
lgfx::delay(1);
}
}
i2c_write_register8_array(axp_i2c_port, axp_i2c_addr, isAxp192 ? reg_data_axp192_second : reg_data_axp2101_second, axp_i2c_freq);
lgfx::delay(1);

result->board = board_t::board_unknown;
if (_detector_spi_t::detect(result, use_reset))
{
return true;
result->board = board_t::board_unknown;
if (_detector_spi_t::detect(result, use_reset))
{
return true;
}
}
}
lgfx::i2c::release(axp_i2c_port);
Expand Down Expand Up @@ -2207,7 +2281,12 @@ namespace lgfx
else
{
ESP_LOGI(LIBRARY_NAME, "[Autodetect] M5StackCore2");
p->light(new Light_M5StackCore2());

auto chk_axp = lgfx::i2c::readRegister8(axp_i2c_port, axp_i2c_addr, 0x03, 400000);
p->light( chk_axp.value() == 0x4A // AXP2101 found
? (lgfx::ILight*)(new Light_M5StackCore2_AXP2101())
: (lgfx::ILight*)(new Light_M5StackCore2())
);
t = new lgfx::Touch_FT5x06();
auto cfg = t->config();
cfg.x_min = 0;
Expand Down

0 comments on commit 0628459

Please sign in to comment.