@@ -158,6 +158,10 @@ M5PM1::M5PM1()
158158 _wire = nullptr ;
159159 _sda = -1 ;
160160 _scl = -1 ;
161+ #if M5PM1_HAS_M5UNIFIED_I2C
162+ _m5_i2c = nullptr ;
163+ _commFreq = 0 ;
164+ #endif
161165#else
162166 _i2cDriverType = M5PM1_I2C_DRIVER_NONE;
163167#if M5PM1_HAS_I2C_MASTER
@@ -334,6 +338,83 @@ m5pm1_err_t M5PM1::begin(TwoWire* wire, uint8_t addr, int8_t sda, int8_t scl, ui
334338 return M5PM1_OK;
335339}
336340
341+ #if M5PM1_HAS_M5UNIFIED_I2C
342+ m5pm1_err_t M5PM1::begin (m5::I2C_Class* i2c, uint8_t addr, uint32_t speed)
343+ {
344+ if (i2c == nullptr || !i2c->isEnabled ()) {
345+ M5PM1_LOG_E (TAG, " M5Unified I2C_Class is null or not initialized" );
346+ return M5PM1_ERR_I2C_CONFIG;
347+ }
348+
349+ _wire = nullptr ;
350+ _m5_i2c = i2c;
351+ _addr = addr;
352+ _sda = -1 ;
353+ _scl = -1 ;
354+
355+ // 步骤1:校验用户频率并记录
356+ // Step 1: Validate requested speed
357+ if (!_isValidI2cFrequency (speed)) {
358+ M5PM1_LOG_W (TAG, " Invalid I2C frequency: %lu Hz. Falling back to 100KHz." , (unsigned long )speed);
359+ _requestedSpeed = M5PM1_I2C_FREQ_100K;
360+ } else {
361+ _requestedSpeed = speed;
362+ }
363+
364+ // 步骤2:以 100KHz 发送唤醒信号
365+ // Step 2: Send wake signal at 100KHz
366+ _commFreq = M5PM1_I2C_FREQ_100K;
367+ M5PM1_M5UNIFIED_SEND_WAKE (_m5_i2c, _addr, _commFreq);
368+ M5PM1_DELAY_MS (10 );
369+
370+ // 步骤3:验证设备通信(失败则等待 800ms 重试一次)
371+ // Step 3: Verify device communication (retry once after 800ms)
372+ if (!_initDevice ()) {
373+ M5PM1_LOG_W (TAG, " Device init failed, retrying after 800ms..." );
374+ M5PM1_DELAY_MS (800 );
375+ M5PM1_M5UNIFIED_SEND_WAKE (_m5_i2c, _addr, _commFreq);
376+ M5PM1_DELAY_MS (10 );
377+ if (!_initDevice ()) {
378+ // 100K 再次失败,尝试 400K
379+ // 100K failed again, try 400K
380+ M5PM1_LOG_W (TAG, " Device init failed at 100KHz (retry), trying 400KHz..." );
381+ _commFreq = M5PM1_I2C_FREQ_400K;
382+ M5PM1_M5UNIFIED_SEND_WAKE (_m5_i2c, _addr, _commFreq);
383+ M5PM1_DELAY_MS (10 );
384+ if (!_initDevice ()) {
385+ M5PM1_LOG_E (TAG, " Failed at 100KHz (twice) and 400KHz" );
386+ _m5_i2c = nullptr ;
387+ return M5PM1_ERR_I2C_COMM;
388+ }
389+ }
390+ }
391+ _initialized = true ;
392+
393+ // 步骤4:配置设备 I2C 参数(关闭睡眠 + 目标频率)
394+ // Step 4: Configure device I2C (disable sleep + target speed)
395+ m5pm1_i2c_speed_t targetSpeed =
396+ (_requestedSpeed == M5PM1_I2C_FREQ_400K) ? M5PM1_I2C_SPEED_400K : M5PM1_I2C_SPEED_100K;
397+ if (setI2cConfig (0 , targetSpeed) != M5PM1_OK) {
398+ M5PM1_LOG_W (TAG, " Failed to set I2C config" );
399+ }
400+
401+ // 步骤5:切换通信频率到目标值(M5Unified 无需重装驱动,直接更新 _commFreq)
402+ // Step 5: Switch to target frequency (no driver reinstall needed; update _commFreq only)
403+ _commFreq = _requestedSpeed;
404+
405+ // 步骤6:刷新快照并完成初始化
406+ // Step 6: Refresh snapshot and finish initialization
407+ _lastCommTime = M5PM1_GET_TIME_MS ();
408+ if (!_snapshotAll ()) {
409+ _clearAll ();
410+ }
411+
412+ _initialized = true ;
413+ M5PM1_LOG_I (TAG, " M5PM1 initialized at address 0x%02X (I2C: %lu Hz)" , _addr, (unsigned long )_requestedSpeed);
414+ return M5PM1_OK;
415+ }
416+ #endif // M5PM1_HAS_M5UNIFIED_I2C
417+
337418#else // ESP-IDF
338419
339420m5pm1_err_t M5PM1::begin (i2c_port_t port, uint8_t addr, int sda, int scl, uint32_t speed)
@@ -1457,7 +1538,14 @@ bool M5PM1::_writeReg(uint8_t reg, uint8_t value)
14571538 bool success = false ;
14581539 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
14591540#ifdef ARDUINO
1460- success = M5PM1_I2C_ARDUINO_WRITE_BYTE (_wire, _addr, reg, value);
1541+ #if M5PM1_HAS_M5UNIFIED_I2C
1542+ if (_m5_i2c) {
1543+ success = M5PM1_M5UNIFIED_WRITE_BYTE (_m5_i2c, _addr, reg, value, _commFreq);
1544+ } else
1545+ #endif
1546+ {
1547+ success = M5PM1_I2C_ARDUINO_WRITE_BYTE (_wire, _addr, reg, value);
1548+ }
14611549#else
14621550 switch (_i2cDriverType) {
14631551#if M5PM1_HAS_I2C_MASTER
@@ -1503,7 +1591,14 @@ bool M5PM1::_writeReg16(uint8_t reg, uint16_t value)
15031591 bool success = false ;
15041592 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
15051593#ifdef ARDUINO
1506- success = M5PM1_I2C_ARDUINO_WRITE_REG16 (_wire, _addr, reg, value);
1594+ #if M5PM1_HAS_M5UNIFIED_I2C
1595+ if (_m5_i2c) {
1596+ success = M5PM1_M5UNIFIED_WRITE_REG16 (_m5_i2c, _addr, reg, value, _commFreq);
1597+ } else
1598+ #endif
1599+ {
1600+ success = M5PM1_I2C_ARDUINO_WRITE_REG16 (_wire, _addr, reg, value);
1601+ }
15071602#else
15081603 switch (_i2cDriverType) {
15091604#if M5PM1_HAS_I2C_MASTER
@@ -1549,7 +1644,14 @@ bool M5PM1::_readReg(uint8_t reg, uint8_t* value)
15491644 bool success = false ;
15501645 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
15511646#ifdef ARDUINO
1552- success = M5PM1_I2C_ARDUINO_READ_BYTE (_wire, _addr, reg, value);
1647+ #if M5PM1_HAS_M5UNIFIED_I2C
1648+ if (_m5_i2c) {
1649+ success = M5PM1_M5UNIFIED_READ_BYTE (_m5_i2c, _addr, reg, value, _commFreq);
1650+ } else
1651+ #endif
1652+ {
1653+ success = M5PM1_I2C_ARDUINO_READ_BYTE (_wire, _addr, reg, value);
1654+ }
15531655#else
15541656 switch (_i2cDriverType) {
15551657#if M5PM1_HAS_I2C_MASTER
@@ -1595,7 +1697,14 @@ bool M5PM1::_readReg16(uint8_t reg, uint16_t* value)
15951697 bool success = false ;
15961698 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
15971699#ifdef ARDUINO
1598- success = M5PM1_I2C_ARDUINO_READ_REG16 (_wire, _addr, reg, value);
1700+ #if M5PM1_HAS_M5UNIFIED_I2C
1701+ if (_m5_i2c) {
1702+ success = M5PM1_M5UNIFIED_READ_REG16 (_m5_i2c, _addr, reg, value, _commFreq);
1703+ } else
1704+ #endif
1705+ {
1706+ success = M5PM1_I2C_ARDUINO_READ_REG16 (_wire, _addr, reg, value);
1707+ }
15991708#else
16001709 switch (_i2cDriverType) {
16011710#if M5PM1_HAS_I2C_MASTER
@@ -1641,7 +1750,14 @@ bool M5PM1::_writeBytes(uint8_t reg, const uint8_t* data, uint8_t len)
16411750 bool success = false ;
16421751 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
16431752#ifdef ARDUINO
1644- success = M5PM1_I2C_ARDUINO_WRITE_BYTES (_wire, _addr, reg, len, data);
1753+ #if M5PM1_HAS_M5UNIFIED_I2C
1754+ if (_m5_i2c) {
1755+ success = M5PM1_M5UNIFIED_WRITE_BYTES (_m5_i2c, _addr, reg, len, data, _commFreq);
1756+ } else
1757+ #endif
1758+ {
1759+ success = M5PM1_I2C_ARDUINO_WRITE_BYTES (_wire, _addr, reg, len, data);
1760+ }
16451761#else
16461762 switch (_i2cDriverType) {
16471763#if M5PM1_HAS_I2C_MASTER
@@ -1687,7 +1803,14 @@ bool M5PM1::_readBytes(uint8_t reg, uint8_t* data, uint8_t len)
16871803 bool success = false ;
16881804 for (int attempt = 0 ; attempt < M5PM1_I2C_RETRY_COUNT; ++attempt) {
16891805#ifdef ARDUINO
1690- success = M5PM1_I2C_ARDUINO_READ_BYTES (_wire, _addr, reg, len, data);
1806+ #if M5PM1_HAS_M5UNIFIED_I2C
1807+ if (_m5_i2c) {
1808+ success = M5PM1_M5UNIFIED_READ_BYTES (_m5_i2c, _addr, reg, len, data, _commFreq);
1809+ } else
1810+ #endif
1811+ {
1812+ success = M5PM1_I2C_ARDUINO_READ_BYTES (_wire, _addr, reg, len, data);
1813+ }
16911814#else
16921815 switch (_i2cDriverType) {
16931816#if M5PM1_HAS_I2C_MASTER
@@ -1860,6 +1983,12 @@ void M5PM1::pinModeWithRes(uint8_t pin, uint8_t mode, m5pm1_err_t* err)
18601983 gpioMode = M5PM1_GPIO_MODE_INPUT;
18611984 pull = M5PM1_GPIO_PULL_NONE;
18621985 break ;
1986+ case OTHER:
1987+ func = M5PM1_GPIO_FUNC_OTHER;
1988+ gpioMode = M5PM1_GPIO_MODE_OUTPUT;
1989+ pull = M5PM1_GPIO_PULL_NONE;
1990+ setDrive = true ;
1991+ break ;
18631992 default :
18641993 M5PM1_LOG_E (TAG, " Invalid mode: 0x%02X" , mode);
18651994 localErr = M5PM1_ERR_INVALID_ARG;
@@ -4650,15 +4779,23 @@ m5pm1_err_t M5PM1::switchI2cSpeed(m5pm1_i2c_speed_t speed)
46504779 M5PM1_DELAY_MS (5 );
46514780
46524781#ifdef ARDUINO
4653- _wire->end ();
4654- M5PM1_DELAY_MS (10 );
4655- if (!_wire->begin (_sda, _scl, targetFreq)) {
4656- M5PM1_LOG_E (TAG, " Failed to re-initialize I2C bus at %lu Hz" , (unsigned long )targetFreq);
4657- _wire->begin (_sda, _scl, originalFreq);
4658- _writeReg (M5PM1_REG_I2C_CFG, originalCfg);
4659- return M5PM1_ERR_I2C_CONFIG;
4782+ #if M5PM1_HAS_M5UNIFIED_I2C
4783+ if (_m5_i2c) {
4784+ _commFreq = targetFreq;
4785+ M5PM1_LOG_I (TAG, " M5Unified I2C frequency updated to %lu Hz" , (unsigned long )targetFreq);
4786+ } else
4787+ #endif
4788+ {
4789+ _wire->end ();
4790+ M5PM1_DELAY_MS (10 );
4791+ if (!_wire->begin (_sda, _scl, targetFreq)) {
4792+ M5PM1_LOG_E (TAG, " Failed to re-initialize I2C bus at %lu Hz" , (unsigned long )targetFreq);
4793+ _wire->begin (_sda, _scl, originalFreq);
4794+ _writeReg (M5PM1_REG_I2C_CFG, originalCfg);
4795+ return M5PM1_ERR_I2C_CONFIG;
4796+ }
4797+ M5PM1_DELAY_MS (10 );
46604798 }
4661- M5PM1_DELAY_MS (10 );
46624799#else
46634800 esp_err_t ret;
46644801 switch (_i2cDriverType) {
@@ -4734,6 +4871,12 @@ m5pm1_err_t M5PM1::switchI2cSpeed(m5pm1_i2c_speed_t speed)
47344871 break ;
47354872 }
47364873#endif // !M5PM1_HAS_I2C_MASTER && !M5PM1_HAS_I2C_BUS
4874+ #if M5PM1_HAS_M5UNIFIED_I2C
4875+ case M5PM1_I2C_DRIVER_M5UNIFIED:
4876+ _commFreq = targetFreq;
4877+ M5PM1_LOG_I (TAG, " M5Unified I2C frequency updated to %lu Hz" , (unsigned long )targetFreq);
4878+ break ;
4879+ #endif
47374880 default :
47384881 M5PM1_LOG_E (TAG, " Unknown I2C driver type" );
47394882 return M5PM1_ERR_INTERNAL;
@@ -4745,10 +4888,17 @@ m5pm1_err_t M5PM1::switchI2cSpeed(m5pm1_i2c_speed_t speed)
47454888 M5PM1_LOG_E (TAG, " Communication failed after switching to %lu Hz, reverting" , (unsigned long )targetFreq);
47464889
47474890#ifdef ARDUINO
4748- _wire->end ();
4749- M5PM1_DELAY_MS (10 );
4750- _wire->begin (_sda, _scl, originalFreq);
4751- M5PM1_DELAY_MS (10 );
4891+ #if M5PM1_HAS_M5UNIFIED_I2C
4892+ if (_m5_i2c) {
4893+ _commFreq = originalFreq;
4894+ } else
4895+ #endif
4896+ {
4897+ _wire->end ();
4898+ M5PM1_DELAY_MS (10 );
4899+ _wire->begin (_sda, _scl, originalFreq);
4900+ M5PM1_DELAY_MS (10 );
4901+ }
47524902#else
47534903 switch (_i2cDriverType) {
47544904#if M5PM1_HAS_I2C_MASTER
@@ -4790,6 +4940,11 @@ m5pm1_err_t M5PM1::switchI2cSpeed(m5pm1_i2c_speed_t speed)
47904940 break ;
47914941 }
47924942#endif // !M5PM1_HAS_I2C_MASTER && !M5PM1_HAS_I2C_BUS
4943+ #if M5PM1_HAS_M5UNIFIED_I2C
4944+ case M5PM1_I2C_DRIVER_M5UNIFIED:
4945+ _commFreq = originalFreq;
4946+ break ;
4947+ #endif
47934948 default :
47944949 break ;
47954950 }
@@ -4829,6 +4984,12 @@ bool M5PM1::isAutoWakeEnabled() const
48294984m5pm1_err_t M5PM1::sendWakeSignal ()
48304985{
48314986#ifdef ARDUINO
4987+ #if M5PM1_HAS_M5UNIFIED_I2C
4988+ if (_m5_i2c) {
4989+ M5PM1_M5UNIFIED_SEND_WAKE (_m5_i2c, _addr, _commFreq);
4990+ return M5PM1_OK;
4991+ }
4992+ #endif
48324993 M5PM1_I2C_ARDUINO_SEND_WAKE (_wire, _addr);
48334994 return M5PM1_OK;
48344995#else
0 commit comments