From 8f1f1a60b3040088cd0ca2b9eb9d024ccc4d907f Mon Sep 17 00:00:00 2001 From: onexs-xsi <850559025@qq.com> Date: Tue, 10 Mar 2026 17:20:32 +0800 Subject: [PATCH] 1. update 1.0.6 2. update neopixel.ino --- README_FUNCTION_CN.md | 149 ++++++++++++++++++--------------- README_FUNCTION_EN.md | 149 ++++++++++++++++++--------------- examples/neopixel/neopixel.ino | 60 ++++++++++--- idf_component.yml | 2 +- library.json | 2 +- library.properties | 2 +- 6 files changed, 216 insertions(+), 148 deletions(-) diff --git a/README_FUNCTION_CN.md b/README_FUNCTION_CN.md index fb92b6d..476151e 100644 --- a/README_FUNCTION_CN.md +++ b/README_FUNCTION_CN.md @@ -1,16 +1,16 @@ # M5PM1 功能总览(中文) -面向 Arduino/ESP-IDF 双平台的 PM1 电源管理驱动库功能分类说明。 +面向 Arduino 与 ESP-IDF 的 PM1 电源管理驱动库功能分类说明。 -- **版本**: 1.0.1 +- **版本**: 1.0.6 - **默认 I2C 地址**: `0x6E` -- **I2C 速度**: 默认 100 kHz,可切换 400 kHz(切换后库内部会处理 I2C 重建) +- **I2C 速度**: 默认 100 kHz,支持切换至 400 kHz ## 项目结构与角色 - `src/M5PM1.h`: 公共 API、寄存器/枚举、缓存结构定义。 - `src/M5PM1.cpp`: 驱动实现、冲突校验、快照与缓存逻辑。 -- `src/M5PM1_i2c_compat.h`: Arduino/ESP-IDF I2C 读写兼容封装。 +- `src/M5PM1_i2c_compat.h`: Arduino / ESP-IDF / M5Unified I2C 兼容封装。 ## 示例 @@ -25,144 +25,159 @@ - **初始化** - Arduino: `begin(TwoWire*, addr, sda, scl, speed)` + - Arduino / ESP-IDF(检测到 M5Unified 时): `begin(m5::I2C_Class*, addr, speed)` - ESP-IDF: `begin(i2c_port_t, addr, sda, scl, speed)` - - ESP-IDF: `begin(i2c_master_bus_handle_t, addr, speed)` - - ESP-IDF: `begin(i2c_bus_handle_t, addr, speed)` + - ESP-IDF(IDF >= 5.3): `begin(i2c_master_bus_handle_t, addr, speed)` + - ESP-IDF(兼容模式可用时): `begin(i2c_bus_handle_t, addr, speed)` - **日志** - - `setLogLevel`/`getLogLevel` + - `setLogLevel` / `getLogLevel` ### 2) 设备信息 -- `getDeviceId`/`getDeviceModel`/`getHwVersion`/`getSwVersion` +- `getDeviceId` / `getDeviceModel` / `getHwVersion` / `getSwVersion` ### 3) GPIO 基础与高级控制 - **Arduino 风格** - - `pinMode`/`digitalWrite`/`digitalRead` + - `pinMode` / `digitalWrite` / `digitalRead` - **带返回值版本** - - `pinModeWithRes`/`digitalWriteWithRes`/`digitalReadWithRes` + - `pinModeWithRes` / `digitalWriteWithRes` / `digitalReadWithRes` - **高级配置** - - `gpioSet`/`gpioSetFunc`/`gpioSetMode`/`gpioSetOutput`/`gpioGetInput` - - `gpioSetPull`/`gpioSetDrive`/`ledEnSetDrive` - - `gpioSetWakeEnable`/`gpioSetWakeEdge` + - `gpioSet` / `gpioSetFunc` / `gpioSetMode` / `gpioSetOutput` / `gpioGetInput` + - `gpioSetPull` / `gpioSetDrive` / `ledEnSetDrive` + - `gpioSetWakeEnable` / `gpioSetWakeEdge` - **引脚状态与校验** - - `dumpPinStatus`/`verifyPinConfig`/`getPinStatus`/`getPinStatusArray` + - `dumpPinStatus` / `verifyPinConfig` / `getPinStatus` / `getPinStatusArray` ### 4) 电源保持 -- `gpioSetPowerHold`/`gpioGetPowerHold` -- `ldoSetPowerHold`/`ldoGetPowerHold` -- `boostSetPowerHold`/`boostGetPowerHold` +- `gpioSetPowerHold` / `gpioGetPowerHold` +- `ldoSetPowerHold` / `ldoGetPowerHold` +- `boostSetPowerHold` / `boostGetPowerHold` ### 5) ADC 与温度 -- `analogRead`/`isAdcBusy`/`disableAdc`/`readTemperature` +- `analogRead` / `isAdcBusy` / `disableAdc` / `readTemperature` ### 6) PWM -- `setPwmFrequency`/`getPwmFrequency` -- `setPwmDuty`/`getPwmDuty` (0-100%) -- `setPwmDuty12bit`/`getPwmDuty12bit` (0-4095) +- `setPwmFrequency` / `getPwmFrequency` +- `setPwmDuty` / `getPwmDuty`(0-100%) +- `setPwmDuty12bit` / `getPwmDuty12bit`(0-4095) - `setPwmConfig` -- `analogWrite` (0-255) +- `analogWrite`(0-255) ### 7) 电压读取 -- `readVref`/`getRefVoltage`/`readVbat`/`readVin`/`read5VInOut` +- `readVref` / `getRefVoltage` / `readVbat` / `readVin` / `read5VInOut` ### 8) 电源管理与电池 - `getPowerSource` -- `getWakeSource`/`clearWakeSource` -- `setPowerConfig`/`getPowerConfig`/`clearPowerConfig` -- `setChargeEnable`/`setDcdcEnable`/`setLdoEnable`/`setBoostEnable`/`setLedEnLevel` +- `getWakeSource` / `clearWakeSource` +- `setPowerConfig` / `getPowerConfig` / `clearPowerConfig` +- `setChargeEnable` / `setDcdcEnable` / `setLdoEnable` / `setBoostEnable` / `setLedEnLevel` - `setBatteryLvp` ### 9) 看门狗与定时器 -- `wdtSet`/`wdtFeed`/`wdtGetCount` -- `timerSet`/`timerClear` +- `wdtSet` / `wdtFeed` / `wdtGetCount` +- `timerSet` / `timerClear` ### 10) 按钮 -- `btnSetConfig`/`btnGetState`/`btnGetFlag` -- `setSingleResetDisable`(高危)/`getSingleResetDisable` -- `setDoubleOffDisable`(高危)/`getDoubleOffDisable` +- `btnSetConfig` / `btnGetState` / `btnGetFlag` +- `setSingleResetDisable`(高危) / `getSingleResetDisable` +- `setDoubleOffDisable`(高危) / `getDoubleOffDisable` ### 11) 中断 - **状态读取与清除** - - `irqGetGpioStatus`/`irqClearGpioAll` - - `irqGetSysStatus`/`irqClearSysAll` - - `irqGetBtnStatus`/`irqClearBtnAll` + - `irqGetGpioStatus` / `irqClearGpioAll` + - `irqGetSysStatus` / `irqClearSysAll` + - `irqGetBtnStatus` / `irqClearBtnAll` - **枚举式读取** - - `irqGetGpioStatusEnum`/`irqGetSysStatusEnum`/`irqGetBtnStatusEnum` + - `irqGetGpioStatusEnum` / `irqGetSysStatusEnum` / `irqGetBtnStatusEnum` - **中断屏蔽** - - GPIO: `irqSetGpioMask(m5pm1_irq_gpio_t, m5pm1_irq_mask_ctrl_t)`/`irqGetGpioMask`/`irqSetGpioMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetGpioMaskBits` - - 系统: `irqSetSysMask(m5pm1_irq_sys_t, m5pm1_irq_mask_ctrl_t)`/`irqGetSysMask`/`irqSetSysMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetSysMaskBits` - - 按钮: `irqSetBtnMask(m5pm1_btn_irq_t, m5pm1_irq_mask_ctrl_t)`/`irqGetBtnMask`/`irqSetBtnMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetBtnMaskBits` - - 注意: 单个设置接口不支持 `ALL`/`NONE` 枚举值,批量操作请使用 `xxxMaskAll()` 函数 + - GPIO: `irqSetGpioMask(m5pm1_irq_gpio_t, m5pm1_irq_mask_ctrl_t)` / `irqGetGpioMask` / `irqSetGpioMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetGpioMaskBits` + - 系统: `irqSetSysMask(m5pm1_irq_sys_t, m5pm1_irq_mask_ctrl_t)` / `irqGetSysMask` / `irqSetSysMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetSysMaskBits` + - 按钮: `irqSetBtnMask(m5pm1_irq_btn_t, m5pm1_irq_mask_ctrl_t)` / `irqGetBtnMask` / `irqSetBtnMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetBtnMaskBits` + - 注意: 单个设置接口不支持 `ALL` / `NONE` 枚举值,批量操作请使用 `xxxMaskAll()` 函数。 ### 12) 系统命令 -- `sysCmd`/`shutdown`/`reboot`/`enterDownloadMode` -- `setDownloadLock`(高危)/`getDownloadLock` +- `sysCmd` / `shutdown` / `reboot` / `enterDownloadMode` +- `setDownloadLock`(高危) / `getDownloadLock` ### 13) NeoPixel -- `setLeds`/`setLedCount`/`setLedColor`/`refreshLeds`/`disableLeds` +- `setLeds` / `setLedCount` / `setLedColor` / `refreshLeds` / `disableLeds` ### 14) AW8737A 脉冲控制 - **脉冲模式** - `setAw8737aPulse(pin, pulseNum, refresh)`: 设置脉冲数量(0-3) - `refreshAw8737aPulse`: 触发脉冲刷新 -- **增益模式**(语义化别名) +- **增益模式** - `setAw8737aMode(pin, mode, refresh)`: 设置增益模式(MODE_1 到 MODE_4) - `refreshAw8737aMode`: 触发模式刷新 - **注意事项** - - 如果引脚不是输出模式,会自动配置为推挽输出 - - 如果使用开漏输出,需要外部上拉电阻 - - refresh=NOW 时执行后会有 20ms 延迟 + - 如果引脚不是输出模式,会自动配置为推挽输出。 + - 如果使用开漏输出,需要外部上拉电阻。 + - `refresh = NOW` 时执行后会有约 20 ms 延迟。 ### 15) RTC RAM -- `writeRtcRAM`/`readRtcRAM` +- `writeRtcRAM` / `readRtcRAM` ### 16) I2C 配置与自动唤醒 -- `setI2cConfig`/`switchI2cSpeed`/`getI2cSpeed` -- `setI2cSleepTime`/`getI2cSleepTime` -- `setAutoWakeEnable`/`isAutoWakeEnabled`/`sendWakeSignal` +- `setI2cConfig` / `switchI2cSpeed` / `getI2cSpeed` +- `setI2cSleepTime` / `getI2cSleepTime` +- `setAutoWakeEnable` / `isAutoWakeEnabled` / `sendWakeSignal` - 兼容层: `M5PM1_i2c_compat.h` -### 17) 状态快照/缓存/校验 +### 17) 状态快照 / 缓存 / 校验 -- `setAutoSnapshot`/`isAutoSnapshotEnabled`/`updateSnapshot`/`verifySnapshot` +- `setAutoSnapshot` / `isAutoSnapshotEnabled` / `updateSnapshot` / `verifySnapshot` - `validateConfig` -- `getCachedPwmFrequency`/`getCachedPwmState`/`getCachedAdcState` -- `getCachedPowerConfig`/`getCachedButtonConfig` -- `getCachedIrqMasks`/`getCachedIrqStatus` +- `getCachedPwmFrequency` / `getCachedPwmState` / `getCachedAdcState` +- `getCachedPowerConfig` / `getCachedButtonConfig` +- `getCachedIrqMasks` / `getCachedIrqStatus` -## 注意事项 +## 兼容性与使用注意 -如果使用 `setDownloadLock`、`setSingleResetDisable`、`setDoubleOffDisable` 高危函数导致无法启用烧录、单击复位、双击关断,请拔插电池(内置电池设备可能损坏壳体和器件)或快速短接 BAT 和 GND(此操作可能损坏电池)。 +### 与 M5Unified / M5GFX 共用 I2C + +- 如果项目中使用 `M5Unified` 或 `M5GFX`,优先使用 `begin(&M5.In_I2C, addr, speed)`。 +- 此时 `M5PM1` 只借用现有 I2C 句柄,不负责驱动安装和释放。 +- 在包含 `M5Unified` 的 ESP-IDF 工程中,建议先包含 `M5Unified.h`,再包含 `M5PM1.h`,以避免 `i2c_config_t` 头文件冲突。 + +### i2c_bus 模式限制 + +- 只要项目中存在 `M5Unified` 或 `M5GFX`,就不应使用 `i2c_bus` 模式。 +- `i2c_bus_handle_t` 初始化入口仅在兼容条件满足时可用;若不可用,对应重载会返回 `M5PM1_ERR_NOT_SUPPORTED`。 + +### 高危接口 + +- `setDownloadLock`、`setSingleResetDisable`、`setDoubleOffDisable` 可能导致下载模式、单击复位或双击关断不可用。 +- 如果误配置后设备无法进入预期状态,通常需要断电后重新上电恢复;对带电池设备请谨慎操作。 ## 引脚与功能限制 | 功能区域 | 说明 | 备注 | | :--- | :--- | :--- | -| **WAKE 互斥** | GPIO0/2 互斥;GPIO3/4 互斥 | 仅 WAKE 功能生效 | -| **唤醒 (WAKE)** | GPIO0/2/3/4 支持唤醒 | GPIO1 不支持 WAKE | -| **ADC 通道** | GPIO1=ADC1, GPIO2=ADC2 | 温度为内部通道 | -| **PWM 通道** | GPIO3=PWM0, GPIO4=PWM1 | 频率全通道共享 | -| **NeoPixel** | 仅 GPIO0 支持;LED 数量 1-31;数据区 0x60 - 0x9F | 刷新时 I2C 短暂不可中断 | -| **I2C 休眠** | 空闲超时可进入低功耗 | PWM 使能或下载模式下休眠失效 | -| **寄存器区块** | 0x00 - 0x0C, 0x10 - 0x19, 0x20 - 0x2A, 0x30 - 0x35, 0x38 - 0x3D, 0x40 - 0x45, 0x48 - 0x4A, 0x50, 0x53, 0x60 - 0x9F, 0xA0 - 0xBF | 支持连续读写 | +| **WAKE 互斥** | GPIO0 / 2 互斥;GPIO3 / 4 互斥 | 仅 WAKE 功能生效 | +| **唤醒 (WAKE)** | GPIO0 / 2 / 3 / 4 支持唤醒 | GPIO1 不支持 WAKE | +| **ADC 通道** | GPIO1 = ADC1,GPIO2 = ADC2 | 温度为内部通道 | +| **PWM 通道** | GPIO3 = PWM0,GPIO4 = PWM1 | 频率全通道共享 | +| **NeoPixel** | 仅 GPIO0 支持;LED 数量 1-32;数据区 0x60 - 0x9F | 刷新时 I2C 短暂不可中断 | +| **I2C 休眠** | 空闲超时后可进入低功耗 | PWM 使能或下载模式下休眠失效 | +| **寄存器区块** | 0x00 - 0x0C,0x10 - 0x19,0x20 - 0x2A,0x30 - 0x35,0x38 - 0x3D,0x40 - 0x45,0x48 - 0x4A,0x50,0x53,0x60 - 0x9F,0xA0 - 0xBF | 支持连续读写 | ## 版本与依赖 -- **版本**: 1.0.1 -- **平台**: Arduino / ESP-IDF (>=4.4) -- **依赖**: espressif/i2c_bus +- **版本**: 1.0.6 +- **平台**: Arduino / ESP-IDF +- **依赖**: 默认无强制外部库依赖;ESP-IDF 下的 `i2c_bus_handle_t` 路径仅在兼容配置满足时可用。 diff --git a/README_FUNCTION_EN.md b/README_FUNCTION_EN.md index 9508fc4..6c81d08 100644 --- a/README_FUNCTION_EN.md +++ b/README_FUNCTION_EN.md @@ -1,20 +1,20 @@ # M5PM1 Function Overview (English) -Feature overview of the PM1 power management driver library for Arduino/ESP-IDF. +Feature overview of the PM1 power management driver library for Arduino and ESP-IDF. -- **Version**: 1.0.1 +- **Version**: 1.0.6 - **Default I2C address**: `0x6E` -- **I2C speed**: Default 100 kHz, can switch to 400 kHz (the library rebuilds I2C internally after switching) +- **I2C speed**: Default 100 kHz, supports switching to 400 kHz ## Project Structure and Roles - `src/M5PM1.h`: Public APIs, registers/enums, cache structure definitions. - `src/M5PM1.cpp`: Driver implementation, conflict checks, snapshot and cache logic. -- `src/M5PM1_i2c_compat.h`: Arduino/ESP-IDF I2C compatibility wrapper. +- `src/M5PM1_i2c_compat.h`: Arduino / ESP-IDF / M5Unified I2C compatibility wrapper. ## Examples -- `examples/basic_power_adc/basic_power_adc.ino`: Initialization, device info, VBAT/VIN/5V readings, ADC/temperature sampling, power rail control. +- `examples/basic_power_adc/basic_power_adc.ino`: Initialization, device info, VBAT/VIN/5V readings, ADC/temperature sampling, and power rail control. - `examples/gpio_pwm/gpio_pwm.ino`: GPIO output/input reads and PWM breathing LED demo. - `examples/usb_interrupt_sleep/usb_interrupt_sleep.ino`: USB plug/unplug interrupt, timer wake, and shutdown demo. - `examples/neopixel/neopixel.ino`: NeoPixel rainbow demo. @@ -25,143 +25,158 @@ Feature overview of the PM1 power management driver library for Arduino/ESP-IDF. - **Initialization** - Arduino: `begin(TwoWire*, addr, sda, scl, speed)` + - Arduino / ESP-IDF (when M5Unified is detected): `begin(m5::I2C_Class*, addr, speed)` - ESP-IDF: `begin(i2c_port_t, addr, sda, scl, speed)` - - ESP-IDF: `begin(i2c_master_bus_handle_t, addr, speed)` - - ESP-IDF: `begin(i2c_bus_handle_t, addr, speed)` + - ESP-IDF (IDF >= 5.3): `begin(i2c_master_bus_handle_t, addr, speed)` + - ESP-IDF (when compatibility mode is available): `begin(i2c_bus_handle_t, addr, speed)` - **Logging** - - `setLogLevel`/`getLogLevel` + - `setLogLevel` / `getLogLevel` ### 2) Device Information -- `getDeviceId`/`getDeviceModel`/`getHwVersion`/`getSwVersion` +- `getDeviceId` / `getDeviceModel` / `getHwVersion` / `getSwVersion` ### 3) GPIO Basics and Advanced Control - **Arduino style** - - `pinMode`/`digitalWrite`/`digitalRead` + - `pinMode` / `digitalWrite` / `digitalRead` - **With return status** - - `pinModeWithRes`/`digitalWriteWithRes`/`digitalReadWithRes` + - `pinModeWithRes` / `digitalWriteWithRes` / `digitalReadWithRes` - **Advanced configuration** - - `gpioSet`/`gpioSetFunc`/`gpioSetMode`/`gpioSetOutput`/`gpioGetInput` - - `gpioSetPull`/`gpioSetDrive`/`ledEnSetDrive` - - `gpioSetWakeEnable`/`gpioSetWakeEdge` + - `gpioSet` / `gpioSetFunc` / `gpioSetMode` / `gpioSetOutput` / `gpioGetInput` + - `gpioSetPull` / `gpioSetDrive` / `ledEnSetDrive` + - `gpioSetWakeEnable` / `gpioSetWakeEdge` - **Pin status and validation** - - `dumpPinStatus`/`verifyPinConfig`/`getPinStatus`/`getPinStatusArray` + - `dumpPinStatus` / `verifyPinConfig` / `getPinStatus` / `getPinStatusArray` ### 4) Power Hold -- `gpioSetPowerHold`/`gpioGetPowerHold` -- `ldoSetPowerHold`/`ldoGetPowerHold` -- `boostSetPowerHold`/`boostGetPowerHold` +- `gpioSetPowerHold` / `gpioGetPowerHold` +- `ldoSetPowerHold` / `ldoGetPowerHold` +- `boostSetPowerHold` / `boostGetPowerHold` ### 5) ADC and Temperature -- `analogRead`/`isAdcBusy`/`disableAdc`/`readTemperature` +- `analogRead` / `isAdcBusy` / `disableAdc` / `readTemperature` ### 6) PWM -- `setPwmFrequency`/`getPwmFrequency` -- `setPwmDuty`/`getPwmDuty` (0-100%) -- `setPwmDuty12bit`/`getPwmDuty12bit` (0-4095) +- `setPwmFrequency` / `getPwmFrequency` +- `setPwmDuty` / `getPwmDuty` (0-100%) +- `setPwmDuty12bit` / `getPwmDuty12bit` (0-4095) - `setPwmConfig` - `analogWrite` (0-255) ### 7) Voltage Reading -- `readVref`/`getRefVoltage`/`readVbat`/`readVin`/`read5VInOut` +- `readVref` / `getRefVoltage` / `readVbat` / `readVin` / `read5VInOut` ### 8) Power Management and Battery - `getPowerSource` -- `getWakeSource`/`clearWakeSource` -- `setPowerConfig`/`getPowerConfig`/`clearPowerConfig` -- `setChargeEnable`/`setDcdcEnable`/`setLdoEnable`/`setBoostEnable`/`setLedEnLevel` +- `getWakeSource` / `clearWakeSource` +- `setPowerConfig` / `getPowerConfig` / `clearPowerConfig` +- `setChargeEnable` / `setDcdcEnable` / `setLdoEnable` / `setBoostEnable` / `setLedEnLevel` - `setBatteryLvp` ### 9) Watchdog and Timer -- `wdtSet`/`wdtFeed`/`wdtGetCount` -- `timerSet`/`timerClear` +- `wdtSet` / `wdtFeed` / `wdtGetCount` +- `timerSet` / `timerClear` ### 10) Button -- `btnSetConfig`/`btnGetState`/`btnGetFlag` -- `setSingleResetDisable` (High risk)/`getSingleResetDisable` -- `setDoubleOffDisable` (High risk)/`getDoubleOffDisable` +- `btnSetConfig` / `btnGetState` / `btnGetFlag` +- `setSingleResetDisable` (high risk) / `getSingleResetDisable` +- `setDoubleOffDisable` (high risk) / `getDoubleOffDisable` ### 11) Interrupts - **Status read and clear** - - `irqGetGpioStatus`/`irqClearGpioAll` - - `irqGetSysStatus`/`irqClearSysAll` - - `irqGetBtnStatus`/`irqClearBtnAll` + - `irqGetGpioStatus` / `irqClearGpioAll` + - `irqGetSysStatus` / `irqClearSysAll` + - `irqGetBtnStatus` / `irqClearBtnAll` - **Enum-style read** - - `irqGetGpioStatusEnum`/`irqGetSysStatusEnum`/`irqGetBtnStatusEnum` + - `irqGetGpioStatusEnum` / `irqGetSysStatusEnum` / `irqGetBtnStatusEnum` - **Interrupt masks** - - GPIO: `irqSetGpioMask(m5pm1_irq_gpio_t, m5pm1_irq_mask_ctrl_t)`/`irqGetGpioMask`/`irqSetGpioMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetGpioMaskBits` - - System: `irqSetSysMask(m5pm1_irq_sys_t, m5pm1_irq_mask_ctrl_t)`/`irqGetSysMask`/`irqSetSysMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetSysMaskBits` - - Button: `irqSetBtnMask(m5pm1_btn_irq_t, m5pm1_irq_mask_ctrl_t)`/`irqGetBtnMask`/`irqSetBtnMaskAll(m5pm1_irq_mask_ctrl_t)`/`irqGetBtnMaskBits` - - Note: Single set interfaces do not support `ALL`/`NONE` enum values, use `xxxMaskAll()` for batch operations + - GPIO: `irqSetGpioMask(m5pm1_irq_gpio_t, m5pm1_irq_mask_ctrl_t)` / `irqGetGpioMask` / `irqSetGpioMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetGpioMaskBits` + - System: `irqSetSysMask(m5pm1_irq_sys_t, m5pm1_irq_mask_ctrl_t)` / `irqGetSysMask` / `irqSetSysMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetSysMaskBits` + - Button: `irqSetBtnMask(m5pm1_irq_btn_t, m5pm1_irq_mask_ctrl_t)` / `irqGetBtnMask` / `irqSetBtnMaskAll(m5pm1_irq_mask_ctrl_t)` / `irqGetBtnMaskBits` + - Note: Single-item setters do not support the `ALL` / `NONE` enum values. Use `xxxMaskAll()` for batch operations. ### 12) System Commands -- `sysCmd`/`shutdown`/`reboot`/`enterDownloadMode` -- `setDownloadLock` (High risk)/`getDownloadLock` +- `sysCmd` / `shutdown` / `reboot` / `enterDownloadMode` +- `setDownloadLock` (high risk) / `getDownloadLock` ### 13) NeoPixel -- `setLeds`/`setLedCount`/`setLedColor`/`refreshLeds`/`disableLeds` +- `setLeds` / `setLedCount` / `setLedColor` / `refreshLeds` / `disableLeds` ### 14) AW8737A Pulse Control -- **Pulse Mode** +- **Pulse mode** - `setAw8737aPulse(pin, pulseNum, refresh)`: Set pulse count (0-3) - `refreshAw8737aPulse`: Trigger pulse refresh -- **Gain Mode** (semantic aliases) +- **Gain mode** - `setAw8737aMode(pin, mode, refresh)`: Set gain mode (MODE_1 to MODE_4) - `refreshAw8737aMode`: Trigger mode refresh - **Notes** - - If pin is not output mode, it will be auto-configured as push-pull output - - If using open-drain output, external pull-up is required - - When refresh=NOW, there will be a 20ms delay after execution + - If the pin is not already an output, it will be auto-configured as push-pull output. + - If open-drain output is used, an external pull-up is required. + - When `refresh = NOW`, execution includes an approximately 20 ms delay. ### 15) RTC RAM -- `writeRtcRAM`/`readRtcRAM` +- `writeRtcRAM` / `readRtcRAM` ### 16) I2C Configuration and Auto Wake -- `setI2cConfig`/`switchI2cSpeed`/`getI2cSpeed` -- `setI2cSleepTime`/`getI2cSleepTime` -- `setAutoWakeEnable`/`isAutoWakeEnabled`/`sendWakeSignal` +- `setI2cConfig` / `switchI2cSpeed` / `getI2cSpeed` +- `setI2cSleepTime` / `getI2cSleepTime` +- `setAutoWakeEnable` / `isAutoWakeEnabled` / `sendWakeSignal` - Compatibility layer: `M5PM1_i2c_compat.h` -### 17) State Snapshot/Cache/Validation +### 17) State Snapshot / Cache / Validation -- `setAutoSnapshot`/`isAutoSnapshotEnabled`/`updateSnapshot`/`verifySnapshot` +- `setAutoSnapshot` / `isAutoSnapshotEnabled` / `updateSnapshot` / `verifySnapshot` - `validateConfig` -- `getCachedPwmFrequency`/`getCachedPwmState`/`getCachedAdcState` -- `getCachedPowerConfig`/`getCachedButtonConfig` -- `getCachedIrqMasks`/`getCachedIrqStatus` +- `getCachedPwmFrequency` / `getCachedPwmState` / `getCachedAdcState` +- `getCachedPowerConfig` / `getCachedButtonConfig` +- `getCachedIrqMasks` / `getCachedIrqStatus` -## Precautions +## Compatibility and Usage Notes -If using high-risk functions `setDownloadLock`, `setSingleResetDisable`, or `setDoubleOffDisable` results in the inability to enable download mode, single-click reset, or double-click shutdown, please disconnect/reconnect the battery (devices with built-in batteries may risk damage to the casing and components) or quickly short BAT and GND (this operation may damage the battery). +### Sharing I2C with M5Unified / M5GFX + +- If the project uses `M5Unified` or `M5GFX`, prefer `begin(&M5.In_I2C, addr, speed)`. +- In this path, `M5PM1` only borrows the existing I2C handle and does not manage driver install or teardown. +- In ESP-IDF projects that include `M5Unified`, include `M5Unified.h` before `M5PM1.h` to avoid `i2c_config_t` header conflicts. + +### i2c_bus mode limits + +- `i2c_bus` mode should not be used when `M5Unified` or `M5GFX` is present in the project. +- The `i2c_bus_handle_t` initialization overload is only usable when compatibility conditions are met; otherwise that overload returns `M5PM1_ERR_NOT_SUPPORTED`. + +### High-risk APIs + +- `setDownloadLock`, `setSingleResetDisable`, and `setDoubleOffDisable` can make download mode, single-click reset, or double-click shutdown unavailable. +- If the device becomes unreachable after a bad configuration, a full power cycle is usually required; be careful on battery-powered hardware. ## Pin and Function Limits | Area | Description | Notes | | :--- | :--- | :--- | -| **WAKE mutual exclusion** | GPIO0/2 are mutually exclusive; GPIO3/4 are mutually exclusive | Only for WAKE function | -| **Wake (WAKE)** | GPIO0/2/3/4 support wake | GPIO1 does not support WAKE | -| **ADC channels** | GPIO1=ADC1, GPIO2=ADC2 | Temperature is an internal channel | -| **PWM channels** | GPIO3=PWM0, GPIO4=PWM1 | Frequency shared across channels | -| **NeoPixel** | GPIO0 only; LED count 1-31; data area 0x60 - 0x9F | I2C briefly non-interruptible during refresh | -| **I2C sleep** | Idle timeout can enter low power | Sleep is ineffective when PWM is enabled or in download mode | +| **WAKE mutual exclusion** | GPIO0 / 2 are mutually exclusive; GPIO3 / 4 are mutually exclusive | Applies only to WAKE function | +| **Wake (WAKE)** | GPIO0 / 2 / 3 / 4 support wake | GPIO1 does not support WAKE | +| **ADC channels** | GPIO1 = ADC1, GPIO2 = ADC2 | Temperature is an internal channel | +| **PWM channels** | GPIO3 = PWM0, GPIO4 = PWM1 | Frequency is shared across channels | +| **NeoPixel** | GPIO0 only; LED count 1-32; data area 0x60 - 0x9F | I2C is briefly non-interruptible during refresh | +| **I2C sleep** | Can enter low power after idle timeout | Sleep is ineffective when PWM is enabled or in download mode | | **Register blocks** | 0x00 - 0x0C, 0x10 - 0x19, 0x20 - 0x2A, 0x30 - 0x35, 0x38 - 0x3D, 0x40 - 0x45, 0x48 - 0x4A, 0x50, 0x53, 0x60 - 0x9F, 0xA0 - 0xBF | Supports continuous read/write | ## Version and Dependencies -- **Version**: 1.0.1 -- **Platforms**: Arduino / ESP-IDF (>=4.4) -- **Dependency**: espressif/i2c_bus +- **Version**: 1.0.6 +- **Platforms**: Arduino / ESP-IDF +- **Dependencies**: No mandatory external library dependency by default; the `i2c_bus_handle_t` path on ESP-IDF is only available when compatibility configuration is satisfied. diff --git a/examples/neopixel/neopixel.ino b/examples/neopixel/neopixel.ino index 3071a6c..de61e94 100644 --- a/examples/neopixel/neopixel.ino +++ b/examples/neopixel/neopixel.ino @@ -11,10 +11,28 @@ * NeoPixel 彩虹渐变示例(使用 GPIO0 作为 LED_EN/数据相关功能)。 * NeoPixel rainbow demo (uses GPIO0 for LED_EN/data-related function). * - * 注意:NeoPixel 仅支持 GPIO0,且 LED 数量最大 31(寄存器 5-bit 限制)。 - * Note: NeoPixel is only supported on GPIO0, and LED count max is 31 (5-bit limit). + * 注意:NeoPixel 仅支持 GPIO0,LED 数量最大 32(固件限制)。 + * Note: NeoPixel is only supported on GPIO0, and LED count max is 32 (firmware limit). + * + * GPIO0 NeoPixel 初始化提供两种等效方案,按需选择其一: + * Two equivalent GPIO0 NeoPixel init approaches — choose one: + * + * 方案1(分步配置)/ Approach 1 (step-by-step): + * pm1.gpioSetFunc(M5PM1_GPIO_NUM_0, M5PM1_GPIO_FUNC_OTHER); + * pm1.gpioSetDrive(M5PM1_GPIO_NUM_0, M5PM1_GPIO_DRIVE_PUSHPULL); + * pm1.gpioSetOutput(M5PM1_GPIO_NUM_0, true); + * + * 方案2(简化调用,库内部等效方案1)/ Approach 2 (simplified, internally equivalent): + * pm1.pinMode(M5PM1_GPIO_NUM_0, M5PM1_OTHER); + * + * 本示例默认使用方案2。修改 USE_INIT_APPROACH 为 1 可切换至方案1。 + * This demo defaults to Approach 2. Set USE_INIT_APPROACH to 1 for Approach 1. */ +// 选择初始化方案:1=分步配置 2=简化调用 +// Select init approach: 1=step-by-step 2=simplified +#define USE_INIT_APPROACH 2 + M5PM1 pm1; #define LOGI(fmt, ...) Serial.printf("[PM1][I] " fmt "\r\n", ##__VA_ARGS__) @@ -22,16 +40,16 @@ M5PM1 pm1; #define LOGE(fmt, ...) Serial.printf("[PM1][E] " fmt "\r\n", ##__VA_ARGS__) #ifndef PM1_I2C_SDA -#define PM1_I2C_SDA 47 +#define PM1_I2C_SDA 48 #endif #ifndef PM1_I2C_SCL -#define PM1_I2C_SCL 48 +#define PM1_I2C_SCL 47 #endif #ifndef PM1_I2C_FREQ #define PM1_I2C_FREQ M5PM1_I2C_FREQ_100K #endif -static const uint8_t LED_COUNT = 8; +static const uint8_t LED_COUNT = 1; static const uint8_t BRIGHTNESS = 64; static void printDivider() @@ -86,14 +104,34 @@ void setup() } } - // GPIO0 设置为 OTHER 以启用 NeoPixel;避免与 GPIO/IRQ/WAKE 冲突。 - // Set GPIO0 to OTHER for NeoPixel; avoid GPIO/IRQ/WAKE conflicts. +#if USE_INIT_APPROACH == 1 + // ---- 方案1:分步配置 ---- + // ---- Approach 1: step-by-step configuration ---- + // 将 GPIO0 功能切换为 OTHER(NeoPixel/LED_EN) + // Switch GPIO0 function to OTHER (NeoPixel/LED_EN) pm1.gpioSetFunc(M5PM1_GPIO_NUM_0, M5PM1_GPIO_FUNC_OTHER); - // LED_EN 默认高电平使能灯带。 - // LED_EN default high level enables LEDs. + // 设置推挽驱动 + // Set push-pull drive + pm1.gpioSetDrive(M5PM1_GPIO_NUM_0, M5PM1_GPIO_DRIVE_PUSHPULL); + // 输出高电平使能 + // Output high to enable + pm1.gpioSetOutput(M5PM1_GPIO_NUM_0, true); + LOGI("GPIO0 NeoPixel init: Approach 1 (step-by-step)"); +#else + // ---- 方案2:简化调用(库内部等效方案1)---- + // ---- Approach 2: simplified (internally equivalent to Approach 1) ---- + pm1.pinMode(M5PM1_GPIO_NUM_0, M5PM1_OTHER); + LOGI("GPIO0 NeoPixel init: Approach 2 (simplified)"); +#endif + + // setLedEnLevel() 主要用于 Stamp-S3Bat 产品,该产品使用默认的指示灯引脚作为RGB的供电引脚。 + // 其他产品可根据硬件设计决定是否调用。默认保留以兼容 Stamp-S3Bat。 + // setLedEnLevel() is mainly for the Stamp-S3Bat product, which uses the default indicator LED pin as the power supply pin for RGB. + // Other products may or may not need this depending on hardware design. Kept by default for Stamp-S3Bat compatibility. pm1.setLedEnLevel(true); - // 设置灯带数量(1-31)。 - // Set LED count (1-31). + + // 设置灯珠数量(1-32,固件最大支持32)。 + // Set LED count (1-32, firmware max 32). pm1.setLedCount(LED_COUNT); LOGI("LED count: %u", LED_COUNT); diff --git a/idf_component.yml b/idf_component.yml index 472b765..bc8d1df 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -12,4 +12,4 @@ dependencies: espressif/i2c_bus: version: "^1.0.0" public: true -version: "1.0.5" \ No newline at end of file +version: "1.0.6" \ No newline at end of file diff --git a/library.json b/library.json index ab3c7fe..10cac62 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "M5PM1", - "version": "1.0.5", + "version": "1.0.6", "description": "M5Stack PM1 Power Management IC Driver Library", "keywords": [ "m5stack", diff --git a/library.properties b/library.properties index b5e8db1..f34aa20 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=M5PM1 -version=1.0.5 +version=1.0.6 author=M5Stack maintainer=M5Stack sentence=M5Stack PM1 Power Management IC Driver Library