mirror of
https://github.com/m5stack/M5IOE1.git
synced 2026-05-20 11:49:24 -07:00
1. Optimize language and format
This commit is contained in:
@@ -5,51 +5,63 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* M5IOE1 硬件中断示例
|
||||
* M5IOE1 Hardware Interrupt Example
|
||||
*
|
||||
* 本示例演示如何使用 M5IOE1 库的硬件中断模式
|
||||
* This example demonstrates how to use the M5IOE1 library in HARDWARE
|
||||
* interrupt mode with a physical INT pin connected to GPIO1 of the host MCU.
|
||||
*
|
||||
* 硬件连接
|
||||
* Hardware Connections:
|
||||
* - M5IOE1 SDA -> GPIO 38 (default, configurable)
|
||||
* - M5IOE1 SCL -> GPIO 39 (default, configurable)
|
||||
* - M5IOE1 INT -> GPIO 1 (host MCU interrupt pin)
|
||||
* - IO1 (M5IOE1) -> Button or switch (connect to GND for active LOW)
|
||||
* - M5IOE1 SDA -> GPIO 38 (默认,可配置) (default, configurable)
|
||||
* - M5IOE1 SCL -> GPIO 39 (默认,可配置) (default, configurable)
|
||||
* - M5IOE1 INT -> GPIO 1 (主机 MCU 中断引脚) (host MCU interrupt pin)
|
||||
* - IO1 (M5IOE1) -> 按钮或开关 (连接到 GND 为低电平有效) (Button or switch, connect to GND for active LOW)
|
||||
*
|
||||
* 演示功能
|
||||
* Features demonstrated:
|
||||
* - Initializing M5IOE1 with hardware interrupt pin (INT_PIN)
|
||||
* - Using HARDWARE interrupt mode for instant response
|
||||
* - Attaching multiple interrupt callbacks to different pins
|
||||
* - Using attachInterruptArg() for callback with custom data
|
||||
* - Interrupt enable/disable control
|
||||
* - Reading interrupt status registers
|
||||
* - 使用硬件中断引脚初始化 M5IOE1 (INT_PIN) (Initializing M5IOE1 with hardware interrupt pin)
|
||||
* - 使用硬件中断模式实现即时响应 (Using HARDWARE interrupt mode for instant response)
|
||||
* - 为不同引脚附加多个中断回调 (Attaching multiple interrupt callbacks to different pins)
|
||||
* - 使用 attachInterruptArg() 进行带自定义数据的回调 (Using attachInterruptArg() for callback with custom data)
|
||||
* - 中断启用/禁用控制 (Interrupt enable/disable control)
|
||||
* - 读取中断状态寄存器 (Reading interrupt status registers)
|
||||
*/
|
||||
|
||||
#include <M5IOE1.h>
|
||||
|
||||
// M5IOE1 设备实例
|
||||
// M5IOE1 device instance
|
||||
M5IOE1 ioe1;
|
||||
|
||||
// I2C 配置
|
||||
// I2C configuration
|
||||
#define I2C_SDA_PIN 38
|
||||
#define I2C_SCL_PIN 39
|
||||
#define I2C_FREQ 400000
|
||||
|
||||
// 主机 MCU 上的物理中断引脚 (默认为 GPIO1)
|
||||
// Physical interrupt pin on host MCU (GPIO1 as default)
|
||||
// 将此引脚连接到 M5IOE1 的 INT 引脚
|
||||
// Connect this pin to M5IOE1's INT pin
|
||||
#define INT_PIN 1
|
||||
|
||||
// M5IOE1 I2C 地址 (默认 0x6F)
|
||||
// M5IOE1 I2C address (default 0x6F)
|
||||
#define I2C_ADDR M5IOE1_DEFAULT_ADDR
|
||||
|
||||
// M5IOE1 GPIO 引脚定义
|
||||
// Pin definitions for M5IOE1 GPIOs
|
||||
#define IOE1_PIN_1 M5IOE1_PIN_1 // IO1 on M5IOE1 (pin index 0)
|
||||
#define IOE1_PIN_2 M5IOE1_PIN_2 // IO2 on M5IOE1 (pin index 1)
|
||||
#define IOE1_PIN_1 M5IOE1_PIN_1 // M5IOE1 上的 IO1 (引脚索引 0) (IO1 on M5IOE1, pin index 0)
|
||||
#define IOE1_PIN_2 M5IOE1_PIN_2 // M5IOE1 上的 IO2 (引脚索引 1) (IO2 on M5IOE1, pin index 1)
|
||||
|
||||
// 中断事件计数器
|
||||
// Counter for interrupt events
|
||||
volatile int pin1Counter = 0;
|
||||
volatile int pin2Counter = 0;
|
||||
|
||||
// 用于带参数回调的自定义数据结构
|
||||
// Custom data structure for callback with argument
|
||||
struct ButtonData {
|
||||
const char* name;
|
||||
@@ -60,17 +72,21 @@ struct ButtonData {
|
||||
ButtonData button1Data = {"Button 1", &pin1Counter, IOE1_PIN_1};
|
||||
ButtonData button2Data = {"Button 2", &pin2Counter, IOE1_PIN_2};
|
||||
|
||||
// 引脚 1 的简单回调 (无参数)
|
||||
// Simple callback for pin 1 (without argument)
|
||||
void IRAM_ATTR pin1Callback() {
|
||||
pin1Counter++;
|
||||
}
|
||||
|
||||
// 引脚 2 的带自定义数据参数的回调
|
||||
// Callback with custom data argument for pin 2
|
||||
void IRAM_ATTR pin2CallbackWithArg(void* arg) {
|
||||
ButtonData* data = static_cast<ButtonData*>(arg);
|
||||
if (data) {
|
||||
(*(data->counter))++;
|
||||
// 注意:避免在 ISR 上下文中使用 Serial 打印
|
||||
// Note: Avoid Serial prints in ISR context
|
||||
// 这仅用于演示 - 在实际应用中,使用标志并在 loop 中处理
|
||||
// This is just demonstration - in real apps, use flags and handle in loop
|
||||
}
|
||||
}
|
||||
@@ -83,10 +99,13 @@ void setup() {
|
||||
Serial.println("M5IOE1 Hardware Interrupt Example");
|
||||
Serial.println("========================================\n");
|
||||
|
||||
// 设置日志级别为 INFO
|
||||
// Set log level to INFO
|
||||
M5IOE1::setLogLevel(M5IOE1_LOG_LEVEL_INFO);
|
||||
|
||||
// 使用硬件中断引脚初始化 M5IOE1
|
||||
// Initialize M5IOE1 with hardware interrupt pin
|
||||
// 当提供 intPin 时,硬件中断是默认且最高效的模式
|
||||
// When intPin is provided, HARDWARE mode is the default and most efficient
|
||||
Serial.println("Initializing M5IOE1 in HARDWARE interrupt mode...");
|
||||
Serial.println(" I2C: SDA=" + String(I2C_SDA_PIN) + ", SCL=" + String(I2C_SCL_PIN));
|
||||
@@ -105,6 +124,7 @@ void setup() {
|
||||
|
||||
Serial.println("M5IOE1 initialized successfully!\n");
|
||||
|
||||
// 读取并显示设备信息
|
||||
// Read and display device information
|
||||
uint16_t uid;
|
||||
uint8_t version;
|
||||
@@ -124,17 +144,20 @@ void setup() {
|
||||
|
||||
Serial.println();
|
||||
|
||||
// 将 IO1 和 IO2 配置为带上拉电阻的输入
|
||||
// Configure IO1 and IO2 as inputs with pull-up
|
||||
Serial.println("Configuring IO1 and IO2 as inputs with internal pull-up...");
|
||||
ioe1.pinMode(IOE1_PIN_1, INPUT_PULLUP);
|
||||
ioe1.pinMode(IOE1_PIN_2, INPUT_PULLUP);
|
||||
Serial.println("Pins configured successfully!\n");
|
||||
|
||||
// 为引脚 1 附加下降沿触发的中断 (简单回调)
|
||||
// Attach interrupt to pin 1 with FALLING edge trigger (simple callback)
|
||||
Serial.println("Attaching FALLING edge interrupt to IO1...");
|
||||
ioe1.attachInterrupt(IOE1_PIN_1, pin1Callback, FALLING);
|
||||
Serial.println("IO1 interrupt attached (simple callback)!\n");
|
||||
|
||||
// 为引脚 2 附加上升沿触发的中断 (带参数的回调)
|
||||
// Attach interrupt to pin 2 with RISING edge trigger (callback with argument)
|
||||
Serial.println("Attaching RISING edge interrupt to IO2...");
|
||||
ioe1.attachInterruptArg(IOE1_PIN_2, pin2CallbackWithArg, &button2Data, RISING);
|
||||
@@ -157,24 +180,29 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// 存储当前计数器值以检测变化
|
||||
// Store current counter values to detect changes
|
||||
static int lastPin1Counter = 0;
|
||||
static int lastPin2Counter = 0;
|
||||
|
||||
// 检查引脚 1 中断计数器是否发生变化
|
||||
// Check if pin 1 interrupt counter changed
|
||||
if (pin1Counter != lastPin1Counter) {
|
||||
Serial.println(">>> IO1 INTERRUPT TRIGGERED! <<<");
|
||||
Serial.println(" Count: " + String(pin1Counter));
|
||||
Serial.println(" Edge: FALLING");
|
||||
|
||||
// 读取 IO1 的当前状态
|
||||
// Read current state of IO1
|
||||
int pinState = ioe1.digitalRead(IOE1_PIN_1);
|
||||
Serial.println(" IO1 state: " + String(pinState == LOW ? "LOW" : "HIGH"));
|
||||
|
||||
// 读取并显示中断状态寄存器
|
||||
// Read and display interrupt status register
|
||||
uint16_t status = ioe1.getInterruptStatus();
|
||||
Serial.println(" INT status: 0b" + String(status, BIN));
|
||||
|
||||
// 清除此引脚的中断
|
||||
// Clear the interrupt for this pin
|
||||
ioe1.clearInterrupt(IOE1_PIN_1);
|
||||
Serial.println(" Interrupt cleared\n");
|
||||
@@ -182,6 +210,7 @@ void loop() {
|
||||
lastPin1Counter = pin1Counter;
|
||||
}
|
||||
|
||||
// 检查引脚 2 中断计数器是否发生变化
|
||||
// Check if pin 2 interrupt counter changed
|
||||
if (pin2Counter != lastPin2Counter) {
|
||||
Serial.println(">>> IO2 INTERRUPT TRIGGERED! <<<");
|
||||
@@ -189,14 +218,17 @@ void loop() {
|
||||
Serial.println(" Edge: RISING");
|
||||
Serial.println(" Callback: with argument (ButtonData)");
|
||||
|
||||
// 读取 IO2 的当前状态
|
||||
// Read current state of IO2
|
||||
int pinState = ioe1.digitalRead(IOE1_PIN_2);
|
||||
Serial.println(" IO2 state: " + String(pinState == HIGH ? "HIGH" : "LOW"));
|
||||
|
||||
// 读取并显示中断状态寄存器
|
||||
// Read and display interrupt status register
|
||||
uint16_t status = ioe1.getInterruptStatus();
|
||||
Serial.println(" INT status: 0b" + String(status, BIN));
|
||||
|
||||
// 清除此引脚的中断
|
||||
// Clear the interrupt for this pin
|
||||
ioe1.clearInterrupt(IOE1_PIN_2);
|
||||
Serial.println(" Interrupt cleared\n");
|
||||
@@ -204,18 +236,23 @@ void loop() {
|
||||
lastPin2Counter = pin2Counter;
|
||||
}
|
||||
|
||||
// 处理串口命令
|
||||
// Handle serial commands
|
||||
if (Serial.available() > 0) {
|
||||
char cmd = Serial.read();
|
||||
|
||||
switch (cmd) {
|
||||
case 'e':
|
||||
// 启用 IO1 上的中断
|
||||
// Enable interrupts on IO1
|
||||
Serial.println("Enabling interrupts on IO1...");
|
||||
ioe1.enableInterrupt(IOE1_PIN_1);
|
||||
Serial.println("IO1 interrupts enabled\n");
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
// 禁用 IO1 上的中断
|
||||
// Disable interrupts on IO1
|
||||
Serial.println("Disabling interrupts on IO1...");
|
||||
ioe1.disableInterrupt(IOE1_PIN_1);
|
||||
Serial.println("IO1 interrupts disabled\n");
|
||||
@@ -223,6 +260,8 @@ void loop() {
|
||||
|
||||
case 's':
|
||||
{
|
||||
// 显示中断状态
|
||||
// Show interrupt status
|
||||
uint16_t status = ioe1.getInterruptStatus();
|
||||
Serial.println("Interrupt Status:");
|
||||
Serial.println(" Register: 0b" + String(status, BIN));
|
||||
@@ -234,6 +273,8 @@ void loop() {
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
// 清除所有中断标志
|
||||
// Clear all interrupt flags
|
||||
Serial.println("Clearing all interrupt flags...");
|
||||
for (uint8_t i = 0; i < 14; i++) {
|
||||
ioe1.clearInterrupt(i);
|
||||
@@ -243,6 +284,7 @@ void loop() {
|
||||
|
||||
case '\n':
|
||||
case '\r':
|
||||
// 忽略换行符
|
||||
// Ignore newlines
|
||||
break;
|
||||
|
||||
@@ -253,5 +295,5 @@ void loop() {
|
||||
}
|
||||
}
|
||||
|
||||
delay(10); // Small delay
|
||||
delay(10); // 小延迟 / Small delay
|
||||
}
|
||||
|
||||
@@ -5,44 +5,54 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* M5IOE1 轮询中断示例
|
||||
* M5IOE1 Interrupt Polling Example
|
||||
*
|
||||
* 本示例演示如何在没有物理中断引脚的情况下,以轮询模式使用 M5IOE1 库
|
||||
* This example demonstrates how to use the M5IOE1 library in POLLING mode
|
||||
* without a physical interrupt pin. The library periodically polls the
|
||||
* interrupt status registers to detect GPIO changes.
|
||||
*
|
||||
* 硬件连接
|
||||
* Hardware Connections:
|
||||
* - M5IOE1 SDA -> GPIO 38 (default, configurable)
|
||||
* - M5IOE1 SCL -> GPIO 39 (default, configurable)
|
||||
* - IO1 (M5IOE1) -> Button or switch (connect to GND for active LOW)
|
||||
* - M5IOE1 SDA -> GPIO 38 (默认,可配置) (default, configurable)
|
||||
* - M5IOE1 SCL -> GPIO 39 (默认,可配置) (default, configurable)
|
||||
* - IO1 (M5IOE1) -> 按钮或开关 (连接到 GND 为低电平有效) (Button or switch, connect to GND for active LOW)
|
||||
*
|
||||
* 演示功能
|
||||
* Features demonstrated:
|
||||
* - Initializing M5IOE1 in polling mode (no INT pin)
|
||||
* - Attaching interrupt callback to pin 1 (IO1) with FALLING edge trigger
|
||||
* - Reading device information (UID, version)
|
||||
* - Using attachInterrupt() callback for event handling
|
||||
* - Polling interval configuration
|
||||
* - 以轮询模式初始化 M5IOE1 (无 INT 引脚) (Initializing M5IOE1 in polling mode, no INT pin)
|
||||
* - 为引脚 1 (IO1) 附加下降沿触发的中断回调 (Attaching interrupt callback to pin 1 with FALLING edge)
|
||||
* - 读取设备信息 (UID、版本) (Reading device information: UID, version)
|
||||
* - 使用 attachInterrupt() 回调进行事件处理 (Using attachInterrupt() callback for event handling)
|
||||
* - 轮询间隔配置 (Polling interval configuration)
|
||||
*/
|
||||
|
||||
#include <M5IOE1.h>
|
||||
|
||||
// M5IOE1 设备实例
|
||||
// M5IOE1 device instance
|
||||
M5IOE1 ioe1;
|
||||
|
||||
// I2C 配置
|
||||
// I2C configuration
|
||||
#define I2C_SDA_PIN 38
|
||||
#define I2C_SCL_PIN 39
|
||||
#define I2C_FREQ 400000
|
||||
|
||||
// M5IOE1 I2C 地址 (默认 0x6F)
|
||||
// M5IOE1 I2C address (default 0x6F)
|
||||
#define I2C_ADDR M5IOE1_DEFAULT_ADDR
|
||||
|
||||
// 引脚定义
|
||||
// Pin definitions
|
||||
#define IOE1_PIN_1 M5IOE1_PIN_1 // IO1 on M5IOE1 (pin index 0)
|
||||
#define IOE1_PIN_1 M5IOE1_PIN_1 // M5IOE1 上的 IO1 (引脚索引 0) (IO1 on M5IOE1, pin index 0)
|
||||
|
||||
// 中断事件计数器
|
||||
// Counter for interrupt events
|
||||
volatile int interruptCounter = 0;
|
||||
|
||||
// 引脚 1 下降沿中断的回调函数
|
||||
// Callback function for pin 1 falling edge interrupt
|
||||
void IRAM_ATTR pin1FallingCallback() {
|
||||
interruptCounter++;
|
||||
@@ -56,10 +66,13 @@ void setup() {
|
||||
Serial.println("M5IOE1 Interrupt Polling Example");
|
||||
Serial.println("========================================\n");
|
||||
|
||||
// 设置日志级别为 INFO (默认)
|
||||
// Set log level to INFO (default)
|
||||
M5IOE1::setLogLevel(M5IOE1_LOG_LEVEL_INFO);
|
||||
|
||||
// 以轮询模式初始化 M5IOE1 (无物理 INT 引脚)
|
||||
// Initialize M5IOE1 in POLLING mode (no physical INT pin)
|
||||
// 当未提供 intPin (或设置为 -1) 时,仅支持轮询和禁用模式
|
||||
// When intPin is not provided (or set to -1), only POLLING and DISABLED modes are supported
|
||||
Serial.println("Initializing M5IOE1 in polling mode...");
|
||||
|
||||
@@ -74,6 +87,7 @@ void setup() {
|
||||
|
||||
Serial.println("M5IOE1 initialized successfully!\n");
|
||||
|
||||
// 读取并显示设备信息
|
||||
// Read and display device information
|
||||
uint16_t uid;
|
||||
uint8_t version;
|
||||
@@ -93,19 +107,24 @@ void setup() {
|
||||
|
||||
Serial.println();
|
||||
|
||||
// 将 IO1 配置为带上拉电阻的输入
|
||||
// Configure IO1 as input with pull-up
|
||||
Serial.println("Configuring IO1 as input with internal pull-up...");
|
||||
ioe1.pinMode(IOE1_PIN_1, INPUT_PULLUP);
|
||||
Serial.println("IO1 configured successfully!\n");
|
||||
|
||||
// 为引脚 1 附加下降沿触发的中断
|
||||
// Attach interrupt to pin 1 with FALLING edge trigger
|
||||
// 在轮询模式下,库会定期检查中断状态,并在 IO1 上检测到下降沿时调用此回调
|
||||
// In polling mode, the library will periodically check the interrupt status
|
||||
// and call this callback when a falling edge is detected on IO1
|
||||
Serial.println("Attaching interrupt callback to IO1 (FALLING edge)...");
|
||||
ioe1.attachInterrupt(IOE1_PIN_1, pin1FallingCallback, FALLING);
|
||||
Serial.println("Interrupt attached successfully!\n");
|
||||
|
||||
// 设置轮询间隔为 1 秒 (1000ms)
|
||||
// Set polling interval to 1 second (1000ms)
|
||||
// 默认为 5000ms。更短的间隔 = 更快的响应,但 CPU 使用率更高。
|
||||
// Default is 5000ms. Shorter intervals = faster response but more CPU usage.
|
||||
Serial.println("Setting polling interval to 1.0 second...");
|
||||
if (ioe1.setPollingInterval(1.0f)) {
|
||||
@@ -126,32 +145,40 @@ void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// 存储当前计数器值以检测变化
|
||||
// Store current counter value to detect changes
|
||||
static int lastCounter = 0;
|
||||
|
||||
// 检查中断计数器是否发生变化
|
||||
// Check if interrupt counter changed
|
||||
if (interruptCounter != lastCounter) {
|
||||
Serial.println(">>> INTERRUPT TRIGGERED! Count: " + String(interruptCounter) + " <<<");
|
||||
lastCounter = interruptCounter;
|
||||
|
||||
// 读取 IO1 的当前状态
|
||||
// Read current state of IO1
|
||||
int pinState = ioe1.digitalRead(IOE1_PIN_1);
|
||||
Serial.println(" IO1 state: " + String(pinState == LOW ? "LOW (pressed)" : "HIGH (released)"));
|
||||
|
||||
// 读取并显示中断状态寄存器
|
||||
// Read and display interrupt status register
|
||||
uint16_t status = ioe1.getInterruptStatus();
|
||||
Serial.println(" Interrupt status register: 0b" + String(status, BIN) + "\n");
|
||||
|
||||
// 清除此引脚的中断
|
||||
// Clear the interrupt for this pin
|
||||
ioe1.clearInterrupt(IOE1_PIN_1);
|
||||
}
|
||||
|
||||
// 可选:手动轮询检查 (库会在后台自动执行此操作)
|
||||
// Optional: Manual polling check (the library does this automatically in background)
|
||||
// 这仅用于演示 - 库会自动处理轮询
|
||||
// This is just for demonstration - the library handles polling automatically
|
||||
static unsigned long lastStatusCheck = 0;
|
||||
if (millis() - lastStatusCheck > 5000) {
|
||||
lastStatusCheck = millis();
|
||||
|
||||
// 显示当前轮询模式信息
|
||||
// Display current polling mode info
|
||||
Serial.println("--- Status Update ---");
|
||||
Serial.println(" Total interrupts: " + String(interruptCounter));
|
||||
@@ -159,5 +186,5 @@ void loop() {
|
||||
Serial.println(" Polling mode: ACTIVE (background task)\n");
|
||||
}
|
||||
|
||||
delay(100); // Small delay to prevent excessive CPU usage
|
||||
delay(100); // 小延迟以防止过度的 CPU 使用 / Small delay to prevent excessive CPU usage
|
||||
}
|
||||
|
||||
+259
-130
File diff suppressed because it is too large
Load Diff
+216
-108
File diff suppressed because it is too large
Load Diff
+30
-15
@@ -16,7 +16,8 @@
|
||||
#include "Wire.h"
|
||||
|
||||
// ============================
|
||||
// Arduino I2C 功能 / Arduino I2C Functions
|
||||
// Arduino I2C 功能
|
||||
// Arduino I2C Functions
|
||||
// ============================
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTE
|
||||
@@ -57,7 +58,8 @@ static inline bool M5IOE1_I2C_READ_REG16(TwoWire *wire, uint8_t addr, uint8_t re
|
||||
if (!M5IOE1_I2C_READ_BYTES(wire, addr, reg, 2, buf)) {
|
||||
return false;
|
||||
}
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
*data = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
|
||||
return true;
|
||||
}
|
||||
@@ -92,7 +94,8 @@ static inline bool M5IOE1_I2C_WRITE_BYTES(TwoWire *wire, uint8_t addr, uint8_t s
|
||||
#ifndef M5IOE1_I2C_WRITE_REG16
|
||||
static inline bool M5IOE1_I2C_WRITE_REG16(TwoWire *wire, uint8_t addr, uint8_t reg, uint16_t data) {
|
||||
uint8_t buf[2];
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
buf[0] = (uint8_t)(data & 0xFF);
|
||||
buf[1] = (uint8_t)((data >> 8) & 0xFF);
|
||||
return M5IOE1_I2C_WRITE_BYTES(wire, addr, reg, 2, buf);
|
||||
@@ -110,17 +113,23 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
// ============================
|
||||
// I2C 驱动类型选择 / I2C Driver Type Selection
|
||||
// I2C 驱动类型选择
|
||||
// I2C Driver Type Selection
|
||||
// ============================
|
||||
typedef enum {
|
||||
M5IOE1_I2C_DRIVER_NONE = 0, // 未初始化 / Not initialized
|
||||
M5IOE1_I2C_DRIVER_SELF_CREATED, // 使用 i2c_port_t 自创建 / Self-created using i2c_port_t
|
||||
M5IOE1_I2C_DRIVER_MASTER, // ESP-IDF 原生 i2c_master 驱动 / ESP-IDF native i2c_master driver
|
||||
M5IOE1_I2C_DRIVER_BUS // esp-idf-lib i2c_bus 组件 / esp-idf-lib i2c_bus component
|
||||
M5IOE1_I2C_DRIVER_NONE = 0, // 未初始化
|
||||
// Not initialized
|
||||
M5IOE1_I2C_DRIVER_SELF_CREATED, // 使用 i2c_port_t 自创建
|
||||
// Self-created using i2c_port_t
|
||||
M5IOE1_I2C_DRIVER_MASTER, // ESP-IDF 原生 i2c_master 驱动
|
||||
// ESP-IDF native i2c_master driver
|
||||
M5IOE1_I2C_DRIVER_BUS // esp-idf-lib i2c_bus 组件
|
||||
// esp-idf-lib i2c_bus component
|
||||
} m5ioe1_i2c_driver_t;
|
||||
|
||||
// ============================
|
||||
// ESP-IDF I2C 函数 / ESP-IDF I2C Functions (i2c_bus)
|
||||
// ESP-IDF I2C 函数 (i2c_bus)
|
||||
// ESP-IDF I2C Functions (i2c_bus)
|
||||
// ============================
|
||||
|
||||
#ifndef M5IOE1_I2C_READ_BYTE
|
||||
@@ -140,7 +149,8 @@ static inline esp_err_t M5IOE1_I2C_READ_REG16(i2c_bus_device_handle_t dev, uint8
|
||||
uint8_t buf[2];
|
||||
esp_err_t ret = i2c_bus_read_bytes(dev, reg, 2, buf);
|
||||
if (ret == ESP_OK) {
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
*data = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
|
||||
}
|
||||
return ret;
|
||||
@@ -162,7 +172,8 @@ static inline esp_err_t M5IOE1_I2C_WRITE_BYTES(i2c_bus_device_handle_t dev, uint
|
||||
#ifndef M5IOE1_I2C_WRITE_REG16
|
||||
static inline esp_err_t M5IOE1_I2C_WRITE_REG16(i2c_bus_device_handle_t dev, uint8_t reg, uint16_t data) {
|
||||
uint8_t buf[2];
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
buf[0] = (uint8_t)(data & 0xFF);
|
||||
buf[1] = (uint8_t)((data >> 8) & 0xFF);
|
||||
return i2c_bus_write_bytes(dev, reg, 2, buf);
|
||||
@@ -170,7 +181,8 @@ static inline esp_err_t M5IOE1_I2C_WRITE_REG16(i2c_bus_device_handle_t dev, uint
|
||||
#endif
|
||||
|
||||
// ============================
|
||||
// ESP-IDF I2C 函数 (i2c_master - 原生驱动) / ESP-IDF I2C Functions (i2c_master - native driver)
|
||||
// ESP-IDF I2C 函数 (i2c_master - 原生驱动)
|
||||
// ESP-IDF I2C Functions (i2c_master - native driver)
|
||||
// ============================
|
||||
|
||||
#ifndef M5IOE1_I2C_MASTER_READ_BYTE
|
||||
@@ -190,7 +202,8 @@ static inline esp_err_t M5IOE1_I2C_MASTER_READ_REG16(i2c_master_dev_handle_t dev
|
||||
uint8_t buf[2];
|
||||
esp_err_t ret = i2c_master_transmit_receive(dev, ®, 1, buf, 2, -1);
|
||||
if (ret == ESP_OK) {
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
*data = (uint16_t)buf[0] | ((uint16_t)buf[1] << 8);
|
||||
}
|
||||
return ret;
|
||||
@@ -206,7 +219,8 @@ static inline esp_err_t M5IOE1_I2C_MASTER_WRITE_BYTE(i2c_master_dev_handle_t dev
|
||||
|
||||
#ifndef M5IOE1_I2C_MASTER_WRITE_BYTES
|
||||
static inline esp_err_t M5IOE1_I2C_MASTER_WRITE_BYTES(i2c_master_dev_handle_t dev, uint8_t start_reg, size_t len, const uint8_t *data) {
|
||||
// 需要在数据前添加寄存器地址 / Need to prepend register address
|
||||
// 需要在数据前添加寄存器地址
|
||||
// Need to prepend register address
|
||||
uint8_t *buf = (uint8_t*)malloc(len + 1);
|
||||
if (buf == NULL) return ESP_ERR_NO_MEM;
|
||||
buf[0] = start_reg;
|
||||
@@ -221,7 +235,8 @@ static inline esp_err_t M5IOE1_I2C_MASTER_WRITE_BYTES(i2c_master_dev_handle_t de
|
||||
static inline esp_err_t M5IOE1_I2C_MASTER_WRITE_REG16(i2c_master_dev_handle_t dev, uint8_t reg, uint16_t data) {
|
||||
uint8_t buf[3];
|
||||
buf[0] = reg;
|
||||
// 小端模式:低字节在前 / Little-endian: low byte first
|
||||
// 小端模式:低字节在前
|
||||
// Little-endian: low byte first
|
||||
buf[1] = (uint8_t)(data & 0xFF);
|
||||
buf[2] = (uint8_t)((data >> 8) & 0xFF);
|
||||
return i2c_master_transmit(dev, buf, 3, -1);
|
||||
|
||||
Reference in New Issue
Block a user