Add initial board, HAL, and executor modules
This commit is contained in:
1 parent
3b9e129c88
commit
0b2eebe76d
82 files changed
+20611
No files matched your search
@@ -0,0 +1,257 @@
|
||||
/**
|
||||
* @file board.cc
|
||||
* @brief 板级外设初始化类,包含步进电机、毫米波雷达、I2C总线等外设的初始化函数。
|
||||
* @author zouyuhua
|
||||
* @date 2025年8月7日
|
||||
*
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "esp_log.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/uart.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "hal/gpio_types.h"
|
||||
#include "hal/uart_types.h"
|
||||
#include "esp_check.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "i2c_bus.h"
|
||||
}
|
||||
|
||||
#include "board_sweekar.h"
|
||||
#include "config.h"
|
||||
#define TAG "board_sweekar"
|
||||
/**
|
||||
* @file board.h
|
||||
* @brief 板级外设初始化类
|
||||
*/
|
||||
/**
|
||||
* @brief 步进电机初始化函数
|
||||
*
|
||||
* 配置LEDC定时器和通道用于PWM输出,设置步进电机的工作模式、使能状态、细分模式和方向,
|
||||
* 并初始化PWM占空比为50%。初始化过程中若出现错误,会通过ESP_LOGE输出错误信息及错误码。
|
||||
*/
|
||||
void BoardSweekar::StepperMotorInit(void)
|
||||
{
|
||||
// 配置LEDC用于PWM输出
|
||||
ledc_timer_config_t ledc_timer = {
|
||||
.speed_mode = LEDC_MODE,
|
||||
.duty_resolution = LEDC_DUTY_RES,
|
||||
.timer_num = LEDC_TIMER,
|
||||
.freq_hz = LEDC_FREQ_HZ,
|
||||
.clk_cfg = LEDC_USE_APB_CLK,
|
||||
};
|
||||
esp_err_t err = ledc_timer_config(&ledc_timer);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_BOARD, "步进电机LEDC定时器配置失败,错误码: 0x%x", err);
|
||||
}
|
||||
|
||||
// 配置LEDC通道
|
||||
ledc_channel_config_t ledc_channel = {
|
||||
.gpio_num = LEDC_OUTPUT_IO,
|
||||
.speed_mode = LEDC_MODE,
|
||||
.channel = LEDC_CHANNEL,
|
||||
.timer_sel = LEDC_TIMER,
|
||||
.duty = 0, // 初始占空比0
|
||||
.hpoint = 0
|
||||
};
|
||||
err = ledc_channel_config(&ledc_channel);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_BOARD, "步进电机LEDC通道配置失败,错误码: 0x%x", err);
|
||||
}
|
||||
|
||||
// 检查I2C总线是否已初始化
|
||||
if (bus_handle_ == nullptr) {
|
||||
ESP_LOGE(TAG_BOARD, "I2C总线未初始化,请先调用I2CMasterInit()");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置步进电机工作模式,使能电机,设置步进电机细分模式,设置步进电机方向
|
||||
err = io_expansion_.SetMotorSleepMode(STEPPER_MOTOR_WORK, STEPPER_MOTOR_SLEEP_PORT, STEPPER_MOTOR_WORK);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_BOARD, "步进电机初始化失败,错误码: 0x%x", err);
|
||||
}
|
||||
err = io_expansion_.SetMotorEnableMode(STEPPER_MOTOR_ENABLE_DISABLE, STEPPER_MOTOR_ENABLE_PORT, STEPPER_MOTOR_ENABLE_PIN);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_BOARD, "步进电机初始化失败,错误码: 0x%x", err);
|
||||
}
|
||||
io_expansion_.SetStepperMicrostepMode(4, STEPPER_MOTOR_MADE_PORT, STEPPER_MOTOR_M0_PIN, STEPPER_MOTOR_M1_PIN);
|
||||
err = io_expansion_.StepperMotorSetDir(STEPPER_MOTOR_LEFT, STEPPER_MOTOR_DIR_PORT, STEPPER_MOTOR_DIR_PIN);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_BOARD, "步进电机初始化失败,错误码: 0x%x", err);
|
||||
}
|
||||
|
||||
// 初始PWM占空比设为0%
|
||||
ledc_set_duty(LEDC_MODE, LEDC_CHANNEL, 0);
|
||||
ledc_update_duty(LEDC_MODE, LEDC_CHANNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 毫米波雷达串口初始化函数
|
||||
*
|
||||
* 配置毫米波雷达所使用的串口参数(波特率、数据位、校验位、停止位等),设置串口引脚,
|
||||
* 并安装串口驱动。采用较大的RX/TX FIFO深度以处理突发数据,禁用驱动自带事件队列以避免
|
||||
* 与自定义中断冲突。
|
||||
*/
|
||||
void BoardSweekar::MillimeterWaveRadarUartInit(void)
|
||||
{
|
||||
uart_config_t uart_config = {
|
||||
.baud_rate = RADAR_BAUD_RATE,
|
||||
.data_bits = UART_DATA_8_BITS,
|
||||
.parity = UART_PARITY_DISABLE,
|
||||
.stop_bits = UART_STOP_BITS_1,
|
||||
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
|
||||
.source_clk = UART_SCLK_DEFAULT,
|
||||
};
|
||||
|
||||
// 1. 设置串口参数
|
||||
ESP_ERROR_CHECK(uart_param_config(RADAR_UART_NUM, &uart_config));
|
||||
|
||||
// 2. 设置 UART 引脚
|
||||
ESP_ERROR_CHECK(uart_set_pin(RADAR_UART_NUM, UART_TX_PIN, UART_RX_PIN,
|
||||
UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
||||
|
||||
// 3. 安装 UART 驱动(禁用驱动自带事件队列,避免与自定义中断冲突)
|
||||
// 增加 RX/TX FIFO 深度以处理突发数据
|
||||
ESP_ERROR_CHECK(uart_driver_install(RADAR_UART_NUM, RADAR_BUF_SIZE * 4, RADAR_BUF_SIZE * 4,
|
||||
0, NULL, 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 毫米波雷达中断引脚初始化函数
|
||||
*
|
||||
* 配置毫米波雷达中断引脚为输入模式,禁用上拉电阻,使能下拉电阻,初始禁用中断功能
|
||||
* (如需使用中断需单独进行配置)。
|
||||
*/
|
||||
void BoardSweekar::MillimeterWaveRadarGpioInit(void)
|
||||
{
|
||||
// GPIO配置结构体
|
||||
gpio_config_t io_conf = {
|
||||
.pin_bit_mask = (1ULL << MILLIMETER_WAVE_RADAR_PIN), // 选择GPIO引脚
|
||||
.mode = GPIO_MODE_INPUT, // 设置为输入模式
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_ENABLE, // 使能下拉
|
||||
.intr_type = GPIO_INTR_DISABLE // 禁用中断(如需中断需单独配置)
|
||||
};
|
||||
|
||||
// 配置GPIO
|
||||
gpio_config(&io_conf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief I2C总线及从机设备初始化函数
|
||||
*
|
||||
* 首先配置并创建I2C主机总线,然后依次添加IO扩展板和线性马达作为I2C从机设备到总线上。
|
||||
* 若总线创建或设备添加失败,会输出错误信息并进行相应的资源清理(删除已创建的总线)。
|
||||
* 初始化成功后,会通过ESP_LOGI输出IO扩展板和线性马达的从机地址信息。
|
||||
*
|
||||
* @return esp_err_t 初始化结果,ESP_OK表示成功,其他错误码表示相应的失败原因
|
||||
*/
|
||||
esp_err_t BoardSweekar::I2CMasterInit(void)
|
||||
{
|
||||
static const char *I2C_INIT = "I2C_INIT";
|
||||
|
||||
// 初始化IO扩展板复位引脚
|
||||
gpio_config_t reset_io_conf = {
|
||||
.pin_bit_mask = (1ULL << IO_EXPAND_RSTN),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_ENABLE, // 使能上拉
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE
|
||||
};
|
||||
gpio_config(&reset_io_conf);
|
||||
|
||||
// 执行复位时序:先拉低100ms,再拉高并等待100ms
|
||||
gpio_set_level(IO_EXPAND_RSTN, 0); // 拉低复位
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); // 等待100ms
|
||||
gpio_set_level(IO_EXPAND_RSTN, 1); // 释放复位
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
|
||||
|
||||
ESP_LOGI(I2C_INIT, "IO扩展板复位完成");
|
||||
|
||||
// 创建统一的I2C总线(使用ESP-ADF的i2c_bus)
|
||||
i2c_config_t i2c_cfg = {
|
||||
.mode = I2C_MODE_MASTER,
|
||||
.sda_io_num = I2C0_MASTER_SDA_IO,
|
||||
.scl_io_num = I2C0_MASTER_SCL_IO,
|
||||
.sda_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.scl_pullup_en = GPIO_PULLUP_ENABLE,
|
||||
.master = {
|
||||
.clk_speed = 100000,
|
||||
},
|
||||
};
|
||||
|
||||
// 创建I2C总线(ESP-ADF的audio_board_init会复用这个总线)
|
||||
bus_handle_ = i2c_bus_create(I2C0_MASTER_PORT, &i2c_cfg);
|
||||
if (bus_handle_ == NULL) {
|
||||
ESP_LOGE(TAG, "Failed to create I2C bus");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); // 等待设备启动
|
||||
// ESP-ADF的i2c_bus不需要单独添加设备,直接通过总线句柄和设备地址进行通信
|
||||
|
||||
// 验证线性马达设备是否存在
|
||||
esp_err_t err = i2c_bus_probe_addr(bus_handle_, LINEAR_MOTOR_I2C_SLAVE_ADDR << 1);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(I2C_INIT, "线性马达设备未找到(地址:0x%02X),错误码: 0x%x", LINEAR_MOTOR_I2C_SLAVE_ADDR, err);
|
||||
// 不返回错误,继续初始化
|
||||
} else {
|
||||
ESP_LOGI(I2C_INIT, "线性马达设备检测成功(地址:0x%02X)", LINEAR_MOTOR_I2C_SLAVE_ADDR);
|
||||
}
|
||||
// 验证IO扩展板设备是否存在
|
||||
err = i2c_bus_probe_addr(bus_handle_, I2C_IO_EXPAND_SLAVE_ADDR << 1);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(I2C_INIT, "IO扩展板设备未找到(地址:0x%02X),错误码: 0x%x", I2C_IO_EXPAND_SLAVE_ADDR, err);
|
||||
// 不返回错误,继续初始化其他设备
|
||||
} else {
|
||||
ESP_LOGI(I2C_INIT, "IO扩展板设备检测成功(地址:0x%02X)", I2C_IO_EXPAND_SLAVE_ADDR);
|
||||
}
|
||||
// 验证陀螺仪设备是否存在
|
||||
err = i2c_bus_probe_addr(bus_handle_, GYROSCOPE_I2C_SLAVE_ADDR << 1);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(I2C_INIT, "陀螺仪设备未找到(地址:0x%02X),错误码: 0x%x", GYROSCOPE_I2C_SLAVE_ADDR, err);
|
||||
// 不返回错误,继续初始化
|
||||
} else {
|
||||
ESP_LOGI(I2C_INIT, "陀螺仪设备检测成功(地址:0x%02X)", GYROSCOPE_I2C_SLAVE_ADDR);
|
||||
}
|
||||
|
||||
// 为IO扩展板设置总线句柄和设备地址(使用7位地址)
|
||||
io_expansion_.bus_handle_ = bus_handle_;
|
||||
io_expansion_.device_addr_ = I2C_IO_EXPAND_SLAVE_ADDR << 1;
|
||||
|
||||
// 为线性马达设置总线句柄和设备地址(使用7位地址)
|
||||
linear_motor_.bus_handle_ = bus_handle_;
|
||||
linear_motor_.device_addr_ = LINEAR_MOTOR_I2C_SLAVE_ADDR << 1;
|
||||
|
||||
ESP_LOGI(I2C_INIT, "I2C总线初始化完成");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 开启VBAT to VBAT_5V
|
||||
*
|
||||
* 创建开启升压的电源管理单元
|
||||
*
|
||||
*/
|
||||
void BoardSweekar::VbatToVbat5vInit(void)
|
||||
{
|
||||
// 配置VBAT_5V引脚为输出模式
|
||||
gpio_config_t io_conf = {
|
||||
.pin_bit_mask = (1ULL << VBAT_5V_PIN),
|
||||
.mode = GPIO_MODE_OUTPUT,
|
||||
.pull_up_en = GPIO_PULLUP_DISABLE,
|
||||
.pull_down_en = GPIO_PULLDOWN_DISABLE,
|
||||
.intr_type = GPIO_INTR_DISABLE
|
||||
};
|
||||
gpio_config(&io_conf);
|
||||
// 使能VBAT_5V
|
||||
gpio_set_level(VBAT_5V_PIN, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef __BOARD_H__
|
||||
#define __BOARD_H__
|
||||
#include "config.h"
|
||||
#include "io_expansion_board.h"
|
||||
#include "stepper_motor.h"
|
||||
#include "i2c_bus.h"
|
||||
#include "gyroscope.h"
|
||||
#include "touch_sensor.h"
|
||||
|
||||
class BoardSweekar
|
||||
{
|
||||
private:
|
||||
i2c_bus_handle_t bus_handle_ = nullptr; // 使用ESP-ADF的I2C总线句柄
|
||||
|
||||
public:
|
||||
IOExpansionBoard io_expansion_; // IO扩展板对象
|
||||
LinearMotor linear_motor_; // 线性马达对象
|
||||
Gyroscope gyroscope_; // 陀螺仪对象
|
||||
TouchSensor touch_sensor_; // 触摸传感器对象
|
||||
// 初始化步进电机
|
||||
void StepperMotorInit(void);
|
||||
|
||||
// 初始化串口
|
||||
void MillimeterWaveRadarUartInit(void);
|
||||
|
||||
//初始化毫米波雷达的中断引脚
|
||||
void MillimeterWaveRadarGpioInit(void);
|
||||
|
||||
// 初始化I2C总线
|
||||
esp_err_t I2CMasterInit(void);
|
||||
|
||||
// 初始化VBAT toVBAT_5V引脚
|
||||
void VbatToVbat5vInit(void);
|
||||
|
||||
// 获取I2C总线句柄
|
||||
i2c_bus_handle_t GetBusHandle() const { return bus_handle_; }
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,139 @@
|
||||
/* 定义引脚分配 */
|
||||
#ifndef _BOARD_CONFIG_H_
|
||||
#define _BOARD_CONFIG_H_
|
||||
|
||||
/**
|
||||
* @file config.h
|
||||
* @brief 定义了引脚的分配。
|
||||
* @author zouyuhua
|
||||
* @date 2025年8月7日
|
||||
*
|
||||
*/
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "driver/i2s.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_sys.h" // 用于 esp_rom_delay_us
|
||||
#include "esp_timer.h"
|
||||
#include "esp_mac.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
#include "driver/timer.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "soc/timer_group_struct.h" // 包含TIMERG0、TIMERG1的结构体定义
|
||||
#include "soc/timer_group_reg.h" // 包含定时器相关寄存器宏定义
|
||||
#include "driver/uart.h"
|
||||
#include "esp_err.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "soc/uart_reg.h"
|
||||
#include "linear_motor.h"
|
||||
#include "gyroscope.h"
|
||||
|
||||
#define TAG_BOARD "SWEEKAR_ESP32"
|
||||
/*I2C总线引脚定义*/
|
||||
#define I2C0_MASTER_PORT I2C_NUM_0
|
||||
#define I2C0_MASTER_SDA_IO GPIO_NUM_2
|
||||
#define I2C0_MASTER_SCL_IO GPIO_NUM_3
|
||||
|
||||
/* 步进电机引脚设置 */
|
||||
#define LEDC_OUTPUT_IO GPIO_NUM_42 // 步进电机LEDC引脚输入
|
||||
|
||||
/* 定义屏幕驱动控制引脚 */
|
||||
#define ST7789_PIN_CLK GPIO_NUM_48 // SPI时钟引脚
|
||||
#define ST7789_PIN_DC GPIO_NUM_38 // 数据/命令选择引脚RSEL
|
||||
#define ST7789_PIN_MOSI GPIO_NUM_47 // SPI数据输出引脚
|
||||
#define ST7789_PIN_CS GPIO_NUM_46 // SPI片选引脚
|
||||
#define ST7789_PIN_BL GPIO_NUM_NC // 背光引脚
|
||||
#define ST7789_PIN_RST GPIO_NUM_NC // 复位引脚
|
||||
#define LCD_BL_ACTIVE_LEVEL 0 // 背光有效电平:1=高电平有效(NMOS),0=低电平有效(PMOS)
|
||||
|
||||
#define LCD_WIDTH 172 // 屏幕宽度(水平方向像素数)
|
||||
#define LCD_HEIGHT 320 // 屏幕高度(垂直方向像素数)
|
||||
|
||||
/* 毫米波雷达配置参数 */
|
||||
/* 定义毫米波雷达的中断引脚 */
|
||||
#define MILLIMETER_WAVE_RADAR_PIN GPIO_NUM_35
|
||||
// UART 配置参数
|
||||
#define RADAR_UART_NUM UART_NUM_1 // 使用 UART1
|
||||
#define UART_TX_PIN GPIO_NUM_40 // GPIO43 作为 TX(根据实际硬件连接调整)
|
||||
#define UART_RX_PIN GPIO_NUM_39 // GPIO44 作为 RX
|
||||
#define RADAR_BAUD_RATE 9600 // 雷达波特率
|
||||
#define RADAR_BUF_SIZE 100 // 雷达接收缓冲区大小
|
||||
|
||||
/* IO扩展硬件配置常量 */
|
||||
#define I2C_MASTER_FREQ_HZ 100000 // I2C通信频率(100kHz)(可更改至400000)
|
||||
#define I2C_IO_EXPAND_SLAVE_ADDR 0x5B // AW9523BTQR器件地址
|
||||
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // 中断检测引脚
|
||||
#define ESP_INTR_FLAG_DEFAULT 0 // 中断标志默认值
|
||||
#define IO_EXPAND_RSTN GPIO_NUM_45 // IO扩展板复位引脚
|
||||
|
||||
/* 定义线性马达的I2C从机配置常量 */
|
||||
#define LINEAR_MOTOR_I2C_SLAVE_ADDR 0x5A // 线性马达的I2C从机地址
|
||||
|
||||
/* 定义陀螺仪的I2C从机配置常量 */
|
||||
#define GYROSCOPE_I2C_SLAVE_ADDR 0x6A // 陀螺仪的I2C从机地址
|
||||
#define GYROSCOPE_INPUT_PIN_SEL GPIO_NUM_21 // 陀螺仪中断引脚
|
||||
|
||||
/* 原生触摸引脚配置 */
|
||||
// 触摸按键数量配置
|
||||
// #define TOUCH_BUTTON_NUM 4
|
||||
#define TOUCH_BUTTON_NUM 3
|
||||
// 触摸通道定义
|
||||
// #define TOUCH_PAD_CHANNEL_1 TOUCH_PAD_NUM11 // GPIO11
|
||||
#define TOUCH_PAD_CHANNEL_2 TOUCH_PAD_NUM12 // GPIO12
|
||||
#define TOUCH_PAD_CHANNEL_3 TOUCH_PAD_NUM13 // GPIO13
|
||||
#define TOUCH_PAD_CHANNEL_4 TOUCH_PAD_NUM14 // GPIO14
|
||||
|
||||
/* ES8311音频编解码器配置 (ESP-ADF兼容) */
|
||||
#define AUDIO_INPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_OUTPUT_SAMPLE_RATE 24000
|
||||
#define AUDIO_INPUT_REFERENCE true
|
||||
|
||||
/* I2S GPIO定义 */
|
||||
#define AUDIO_I2S_GPIO_MCLK GPIO_NUM_15
|
||||
#define AUDIO_I2S_GPIO_WS GPIO_NUM_4
|
||||
#define AUDIO_I2S_GPIO_BCLK GPIO_NUM_5
|
||||
#define AUDIO_I2S_GPIO_DIN GPIO_NUM_6
|
||||
#define AUDIO_I2S_GPIO_DOUT GPIO_NUM_7
|
||||
|
||||
/* PA引脚定义 */
|
||||
#define AUDIO_CODEC_PA_PIN GPIO_NUM_NC
|
||||
|
||||
/* I2C配置 */
|
||||
#define AUDIO_CODEC_I2C_SDA_PIN GPIO_NUM_2
|
||||
#define AUDIO_CODEC_I2C_SCL_PIN GPIO_NUM_3
|
||||
#define AUDIO_CODEC_ES8311_ADDR 0x18
|
||||
#define AUDIO_CODEC_ES7210_ADDR 0x40
|
||||
|
||||
/* WS2812 RGB LED配置 */
|
||||
#define WS2812_PIN GPIO_NUM_41 // WS2812数据引脚
|
||||
#define WS2812_NUM_LEDS 2 // WS2812 LED数量
|
||||
|
||||
/* 创建VBAT to VBAT_5V */
|
||||
#define VBAT_5V_PIN GPIO_NUM_NC // VBAT_5V引脚
|
||||
|
||||
/* 定义按键的中断引脚 */
|
||||
#define BUTTON_PIN GPIO_NUM_0 // 按键中断引脚
|
||||
#define RIGHT_BUTTON_PIN GPIO_NUM_8 // 按键中断引脚
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,724 @@
|
||||
#include "io_expansion_board.h"
|
||||
#include "millimeter_wave_radar.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/idf_additions.h"
|
||||
#include "freertos/portable.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include "esp_rom_sys.h"
|
||||
/**
|
||||
* @file io_expansion_board.cc
|
||||
* @brief IO扩展板功能实现类,包含I2C通信、GPIO中断配置、外设控制等功能
|
||||
* @details 实现了IO扩展板的初始化(中断引脚、复位引脚)、寄存器读写、步进电机控制(细分模式、使能、方向、睡眠状态)、
|
||||
* LCD相关引脚控制(背光、复位、片选)、毫米波雷达中断引脚配置等功能,并提供I2C数据读取任务的创建与管理
|
||||
* @author zouyuhua
|
||||
* @date 2025年8月7日
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief 构造函数
|
||||
*/
|
||||
IOExpansionBoard::IOExpansionBoard()
|
||||
: bus_handle_(nullptr),
|
||||
device_addr_(0),
|
||||
i2c_task_event_group_(nullptr),
|
||||
xI2CReadTaskHandle_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
IOExpansionBoard::~IOExpansionBoard()
|
||||
{
|
||||
// 删除任务
|
||||
if (xI2CReadTaskHandle_) {
|
||||
vTaskDelete(xI2CReadTaskHandle_);
|
||||
}
|
||||
|
||||
// if(pI2CReadTaskStackBuffer) {
|
||||
// heap_caps_free(pI2CReadTaskStackBuffer);
|
||||
// pI2CReadTaskStackBuffer = nullptr;
|
||||
// }
|
||||
|
||||
// if(pxI2CReadTaskBuffer) {
|
||||
// vPortFree(pxI2CReadTaskBuffer);
|
||||
// pxI2CReadTaskBuffer = nullptr;
|
||||
// }
|
||||
|
||||
// 删除事件组
|
||||
if (i2c_task_event_group_) {
|
||||
vEventGroupDelete(i2c_task_event_group_);
|
||||
}
|
||||
|
||||
// 移除中断处理
|
||||
if (interrupt_gpio_ != GPIO_NUM_NC) {
|
||||
gpio_isr_handler_remove(interrupt_gpio_);
|
||||
}
|
||||
|
||||
// 删除IO扩展板设备
|
||||
// 使用i2c_bus API时不需要手动删除设备句柄
|
||||
// bus_handle_由board_sweekar统一管理
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 静态中断处理函数
|
||||
*/
|
||||
void IRAM_ATTR IOExpansionBoard::GpioIsrHandler(void* arg)
|
||||
{
|
||||
IOExpansionBoard* instance = static_cast<IOExpansionBoard*>(arg);
|
||||
if (!instance) return;
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
// 设置事件标志位
|
||||
if (instance->i2c_task_event_group_) {
|
||||
xEventGroupSetBitsFromISR(
|
||||
instance->i2c_task_event_group_,
|
||||
BIT0,
|
||||
&xHigherPriorityTaskWoken
|
||||
);
|
||||
}
|
||||
|
||||
// // 唤醒挂起的I2C任务
|
||||
// if (instance->xI2CReadTaskHandle_) {
|
||||
// if (xTaskResumeFromISR(instance->xI2CReadTaskHandle_) == pdTRUE) {
|
||||
// xHigherPriorityTaskWoken = pdTRUE;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 触发上下文切换
|
||||
if (xHigherPriorityTaskWoken) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化GPIO中断检测
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::InterruptGpioInit(gpio_num_t gpio_num)
|
||||
{
|
||||
// 配置IO扩展板中断引脚
|
||||
gpio_config_t io_conf = {};
|
||||
io_conf.intr_type = GPIO_INTR_NEGEDGE;
|
||||
io_conf.pin_bit_mask = 1ULL << gpio_num;
|
||||
io_conf.mode = GPIO_MODE_INPUT;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
|
||||
esp_err_t err = gpio_config(&io_conf);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO配置失败,错误码: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
// 配置中断服务
|
||||
err = gpio_install_isr_service(ESP_INTR_FLAG_LEVEL3);
|
||||
if (err != ESP_OK && err != ESP_ERR_INVALID_STATE) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO中断服务安装失败,错误码: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
// 注册中断处理函数
|
||||
err = gpio_isr_handler_add(gpio_num, GpioIsrHandler, this);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO中断处理函数添加失败,错误码: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
// 创建事件组
|
||||
i2c_task_event_group_ = xEventGroupCreate();
|
||||
if (!i2c_task_event_group_) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "事件组创建失败");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG_GPIO_IO_EXPAND_DETECT, "GPIO%d中断初始化完成", gpio_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化硬件复位引脚
|
||||
* 设置为上拉,需要复位,需要输出低电平为20us的脉冲信号
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::ResetGpioInit(gpio_num_t gpio_num)
|
||||
{
|
||||
reset_gpio_ = gpio_num;
|
||||
|
||||
// 配置复位引脚
|
||||
gpio_config_t io_conf = {};
|
||||
io_conf.intr_type = GPIO_INTR_DISABLE;
|
||||
io_conf.pin_bit_mask = 1ULL << gpio_num;
|
||||
io_conf.mode = GPIO_MODE_OUTPUT;
|
||||
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
|
||||
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE;
|
||||
esp_err_t err = gpio_config(&io_conf);
|
||||
gpio_set_level(gpio_num, 1); // 复位引脚拉高
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO配置失败,错误码: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_GPIO_IO_EXPAND_DETECT, "GPIO%d复位引脚初始化完成", gpio_num);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 复位IO扩展板
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::ResetIoExpand()
|
||||
{
|
||||
if (reset_gpio_ == GPIO_NUM_NC) {
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "复位引脚未初始化");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
// 复位IO扩展板
|
||||
gpio_set_level(reset_gpio_, 0);
|
||||
esp_rom_delay_us(30);
|
||||
gpio_set_level(reset_gpio_, 1);
|
||||
uint8_t ctl_val;
|
||||
//配置P0_0-P0_7的端口为推挽输出模式
|
||||
esp_err_t err = IoexpandReadReg(CTL, &ctl_val);
|
||||
ctl_val |= (1 << 4); // 设置D[4]位为1(GPOMD=1),切换P0为推挽模式
|
||||
err = IoexpandWriteReg(CTL, ctl_val);
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "复位失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "复位成功");
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 写寄存器数据
|
||||
* @param reg_addr 寄存器地址
|
||||
* @param data 要写入的数据
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::IoexpandWriteReg(uint8_t reg_addr, uint8_t data)
|
||||
{
|
||||
return i2c_bus_write_bytes(bus_handle_, device_addr_, ®_addr, 1, &data, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从寄存器读取数据
|
||||
* @param reg_addr 寄存器地址(如INPUT_PORT0、ID等)
|
||||
* @param data 输出参数,用于存储读取到的数据
|
||||
* @return esp_err_t 操作结果(ESP_OK为成功)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::IoexpandReadReg(uint8_t reg_addr, uint8_t* data)
|
||||
{
|
||||
if (data == nullptr){ // 检查输入参数有效性
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// 使用i2c_bus_read_bytes进行寄存器读取
|
||||
esp_err_t err = i2c_bus_read_bytes(bus_handle_, device_addr_, ®_addr, 1, data, 1);
|
||||
if (err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "读取寄存器失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
//设置IO扩展板为输入模式或是输出模式
|
||||
/*
|
||||
* 这里需要根据实际情况设置IO扩展板的模式,比如输入模式还是输出模式,以及各个引脚的配置。
|
||||
* P0_0 对应NFC_RST引脚,需要设置为输出模式,低电平有效。(待测)
|
||||
* P0_1 对应USB_VBUS引脚,需要设置为输出模式,低电平有效。(待测)
|
||||
* P0_2 对应BTN_RIGHT_EAR引脚,需要设置为输出模式,低电平有效。(待测)
|
||||
* P0_3 暂时未使用。
|
||||
* P0_4 对应步进电机方向引脚,需要设置为输出模式,根据需求设置。(待测)
|
||||
* P0_5 对应CHRG引脚(待测)
|
||||
* P0_6 LCD_DC引脚,需要设置为输出模式,根据需求设置电平。(待测)
|
||||
* P0_7 对应步进电机的使能引脚,需要设置为输出模式,根据需求设置。(待测)
|
||||
*
|
||||
*
|
||||
* P1_0 对应EG800K_PWR。(待测)
|
||||
* P1_1 对应LCD_RST,需要设置为输出模式,低电平有效。(待测)
|
||||
* P1_2 对应LCD_CS,需要设置为输出模式,低电平有效。(待测)
|
||||
* P1_3 暂时未使用。
|
||||
* P1_4 对应步进电机的细分模式M1引脚。(待测)
|
||||
* P1_5 对应步进电机的细分模式M0引脚。(待测)
|
||||
* P1_6 对应步进电机的睡眠引脚。(待测)
|
||||
* P1_7 对应RADAR_O雷达的输出引脚。(待测)
|
||||
* */
|
||||
esp_err_t IOExpansionBoard::IoexpandSetMode(void)
|
||||
{
|
||||
uint8_t ctl_val;
|
||||
//配置P0_0-P0_7的端口为推挽输出模式
|
||||
esp_err_t err = IoexpandReadReg(CTL, &ctl_val);
|
||||
ctl_val |= (1 << 4); // 设置D[4]位为1(GPOMD=1),切换P0为推挽模式
|
||||
err = IoexpandWriteReg(CTL, ctl_val);
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P0端口失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P0端口成功");
|
||||
}
|
||||
// 配置P0_0-P0_7的端口为输入还是输出:0-输出;1-输入
|
||||
// err = IoexpandWriteReg(CONFIG_PORT0, 0x04); // 0000 0100
|
||||
err = IoexpandWriteReg(CONFIG_PORT0, 0x24); // 0010 0100
|
||||
// err = IoexpandWriteReg(CONFIG_PORT0, 0x2C); // 0010 1100 0-2,0-3,0-5都是输入
|
||||
|
||||
// D 1101
|
||||
// 9 1001
|
||||
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P0端口失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P0端口成功");
|
||||
}
|
||||
// 配置P1_0-P1_7的端口输出:0-输出;1-输入
|
||||
// err = IoexpandWriteReg(CONFIG_PORT1, 0x84);
|
||||
err = IoexpandWriteReg(CONFIG_PORT1, 0x80); // 1000 0000
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P1端口失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P1端口成功");
|
||||
}
|
||||
// 配置P0_0-P0_7的初始为高电平
|
||||
// 配置P1_0-P1_7的初始为高电平
|
||||
err = IoexpandWriteReg(OUTPUT_PORT0, 0xFD); // 1111 1101
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P0端口初始值失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P0端口初始值成功");
|
||||
}
|
||||
err = IoexpandWriteReg(OUTPUT_PORT1, 0x7E); // 0111 1110
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P1端口初始值失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P1端口初始值成功");
|
||||
}
|
||||
|
||||
err = IoexpandWriteReg(INT_PORT1, 0x7F); // 0111 1111
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "配置P1端口中断使能失败,错误码:0x%x", err);
|
||||
return err;
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "配置P1端口中断使能成功");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的细分模式
|
||||
*/
|
||||
void IOExpansionBoard::SetStepperMicrostepMode(uint8_t mode, uint8_t OUTPUT_PORT, uint8_t m0_pin, uint8_t m1_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
switch (mode) {
|
||||
case 1: //全步输出模式 低低电平
|
||||
/* code */
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m0_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m1_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
break;
|
||||
case 2: //非圆 1/2 高低电平
|
||||
/* code */
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << m0_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m1_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
break;
|
||||
case 3: //1/4 步 低高电平
|
||||
/* code */
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m0_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << m1_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
break;
|
||||
case 4: //1/8 步 高高电平
|
||||
/* code */
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << m0_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << m1_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
break;
|
||||
default: //全步输入模式 低低电平
|
||||
/* code */
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m0_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << m1_pin);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
if(IoexpandWriteReg(OUTPUT_PORT, current_val) != ESP_OK){
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "设置步进电机细分模式失败");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的使能
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetMotorEnableMode(bool enable, uint8_t OUTPUT_PORT, uint8_t enable_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(enable){
|
||||
// 进入工作状态mode
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << enable_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入睡眠状态
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << enable_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 设置步进电机运行方向
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::StepperMotorSetDir(bool dir, uint8_t OUTPUT_PORT, uint8_t pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(dir){
|
||||
// 方向为正转
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机是否进入睡眠或者工作状态(高电平进入工作状态,低电平进入睡眠状态)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetMotorSleepMode(bool mode, uint8_t OUTPUT_PORT, uint8_t nsleep_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(mode){
|
||||
// 进入工作状态mode
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << nsleep_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入睡眠状态
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << nsleep_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*********************************************IO扩展板LCD引脚配置参数***********************************************/
|
||||
/**
|
||||
* @brief 设置 LCD_BL引脚电平(高电平为命令模式,低电平为数据模式)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetLcdBlMode(bool mode, uint8_t OUTPUT_PORT, uint8_t bl_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(mode){
|
||||
// 进入命令模式
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << bl_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入数据模式
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << bl_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置 LCD_RST引脚电平(高电平为复位模式,低电平为工作模式)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetLcdResetMode(bool mode, uint8_t OUTPUT_PORT, uint8_t reset_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(mode){
|
||||
// 进入复位模式
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << reset_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入工作模式
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << reset_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************IO扩展板的输入引脚配置以及中断引脚定义***********************************************/
|
||||
/**
|
||||
* @brief 设置 毫米波雷达的中断引脚
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetRadarInterruptPin(bool mode, uint8_t INPUT_PORT, uint8_t interrupt_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(mode){
|
||||
// 进入输入模式
|
||||
IoexpandReadReg(INPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << interrupt_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(INPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入输出模式
|
||||
IoexpandReadReg(INPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << interrupt_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(INPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 设置 LCD_CS引脚电平(低电平为选中状态,高电平为不选中状态)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::SetLcdCsMode(bool mode, uint8_t OUTPUT_PORT, uint8_t cs_pin)
|
||||
{
|
||||
uint8_t current_val;
|
||||
if(mode){
|
||||
// 进入选中状态
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val &= ~(1 << cs_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
else{
|
||||
// 进入不选中状态
|
||||
IoexpandReadReg(OUTPUT_PORT, ¤t_val);
|
||||
ESP_LOGW(TAG_I2C_IO_EXPAND_TASK, "0x%x", current_val);
|
||||
current_val |= (1 << cs_pin);
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "!!!!!!!!!0x%x", current_val);
|
||||
return IoexpandWriteReg(OUTPUT_PORT, current_val);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief I2C数据读取任务主体
|
||||
*/
|
||||
void IOExpansionBoard::I2cReadTask(void* pvParameters)
|
||||
{
|
||||
IOExpansionBoard* instance = static_cast<IOExpansionBoard*>(pvParameters);
|
||||
if (!instance) {
|
||||
vTaskDelete(nullptr);
|
||||
return;
|
||||
}
|
||||
// 初始化复位引脚
|
||||
esp_err_t err = instance->ResetGpioInit(IO_EXPAND_RSTN);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO复位初始化失败");
|
||||
}
|
||||
// 初始化IO扩展板子的中断引脚
|
||||
err = instance->InterruptGpioInit(GPIO_INPUT_PIN_SEL);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "GPIO中断初始化失败");
|
||||
}
|
||||
// 设置IO扩展板模式
|
||||
instance->IoexpandSetMode();
|
||||
|
||||
// 设置LCD屏幕复位引脚
|
||||
err = instance->SetLcdResetMode(LCD_RST_HIGH, LCD_RST_PORT, LCD_RST_PIN);
|
||||
if(err != ESP_OK){
|
||||
ESP_LOGE(TAG_GPIO_IO_EXPAND_DETECT, "设置LCD屏幕复位引脚失败");
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG_GPIO_IO_EXPAND_DETECT, "设置LCD屏幕复位引脚成功");
|
||||
}
|
||||
instance->IoexpandWriteReg(OUTPUT_PORT0, 0xff);
|
||||
uint8_t current_val;
|
||||
for (;;) {
|
||||
// 等待中断事件触发
|
||||
if (instance->i2c_task_event_group_) {
|
||||
xEventGroupWaitBits(instance->i2c_task_event_group_, BIT0, pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
}
|
||||
// 读取I2C数据
|
||||
instance->IoexpandReadReg(INPUT_PORT1,¤t_val);
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "读取数据: 0x%0X", current_val);
|
||||
if(current_val & (1 << 7)){
|
||||
ESP_LOGI(TAG_GPIO_IO_EXPAND_DETECT, "检测到中断来自雷达引脚(P1_7)\n");
|
||||
// 调用毫米波雷达回调函数
|
||||
if (instance->radar_) {
|
||||
instance->radar_->TriggerRadarDetectCallback();
|
||||
}
|
||||
}
|
||||
|
||||
// vTaskSuspend(nullptr); // 挂起任务等待下次唤醒
|
||||
}
|
||||
}
|
||||
|
||||
// bool IOExpansionBoard::AllocateStaticTaskMemory()
|
||||
// {
|
||||
// printf("IO拓展芯片创建任务前:Internal Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
// printf("IO拓展芯片创建任务前 Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
// // 分配任务栈(PSRAM)
|
||||
// const size_t TASK_STACK_SIZE = 4096;
|
||||
// pI2CReadTaskStackBuffer = (StackType_t*)heap_caps_malloc(
|
||||
// TASK_STACK_SIZE * sizeof(StackType_t),
|
||||
// MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT
|
||||
// );
|
||||
|
||||
// if (!pI2CReadTaskStackBuffer) {
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "Failed to allocate task stack from PSRAM");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // 分配任务控制块(内部RAM)
|
||||
// pxI2CReadTaskBuffer = (StaticTask_t*)pvPortMalloc(sizeof(StaticTask_t));
|
||||
// if (!pxI2CReadTaskBuffer) {
|
||||
// ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "Failed to allocate task TCB from internal RAM");
|
||||
// heap_caps_free(pI2CReadTaskStackBuffer);
|
||||
// pI2CReadTaskStackBuffer = nullptr;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "Static task memory allocated successfully");
|
||||
// printf("IO拓展芯片创建任务后:Internal Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
// printf("IO拓展芯片创建任务后 Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// void IOExpansionBoard::FreeStaticTaskMemory()
|
||||
// {
|
||||
// if (pI2CReadTaskStackBuffer != nullptr) {
|
||||
// heap_caps_free(pI2CReadTaskStackBuffer);
|
||||
// pI2CReadTaskStackBuffer = nullptr;
|
||||
// }
|
||||
|
||||
// if (pxI2CReadTaskBuffer != nullptr) {
|
||||
// vPortFree(pxI2CReadTaskBuffer);
|
||||
// pxI2CReadTaskBuffer = nullptr;
|
||||
// }
|
||||
|
||||
// ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "Static task memory freed");
|
||||
// }
|
||||
|
||||
/**
|
||||
* @brief 创建I2C数据读取任务
|
||||
*/
|
||||
void IOExpansionBoard::CreateI2cReadTask()
|
||||
{
|
||||
printf("创建I2C读取任务之前:Internal Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
printf("创建I2C读取任务之前:PSRAM Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
if (xI2CReadTaskHandle_) {
|
||||
return; // 任务已创建
|
||||
}
|
||||
|
||||
xTaskCreateWithCaps(
|
||||
I2cReadTask,
|
||||
"i2c_read_task",
|
||||
I2C_TASK_STACK,
|
||||
this,
|
||||
I2C_TASK_PRIORITY,
|
||||
&xI2CReadTaskHandle_,
|
||||
MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT
|
||||
);
|
||||
|
||||
if (xI2CReadTaskHandle_ == NULL) {
|
||||
ESP_LOGE(TAG_I2C_IO_EXPAND_TASK, "Failed to create static I2C read task");
|
||||
} else {
|
||||
ESP_LOGI(TAG_I2C_IO_EXPAND_TASK, "Static I2C read task created successfully");
|
||||
}
|
||||
printf("创建I2C读取任务之后:Internal Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||
printf("创建I2C读取任务之后:PSRAM Free: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 启动I2C任务 (整合初始化和任务创建)
|
||||
*/
|
||||
esp_err_t IOExpansionBoard::StartTask()
|
||||
{
|
||||
// 再创建任务
|
||||
if (!xI2CReadTaskHandle_) {
|
||||
CreateI2cReadTask();
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
#ifndef IO_EXPANSION_BOARD_H
|
||||
#define IO_EXPANSION_BOARD_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <esp_log.h>
|
||||
#include <esp_check.h>
|
||||
#include <esp_timer.h>
|
||||
#include <driver/gpio.h>
|
||||
#include "i2c_bus.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/event_groups.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/queue.h>
|
||||
#include <freertos/semphr.h>
|
||||
#include "esp_err.h"
|
||||
#include "config.h"
|
||||
#include "portmacro.h"
|
||||
|
||||
// 前向声明,避免循环引用
|
||||
class MillimeterWaveRadar;
|
||||
|
||||
/* 寄存器地址 */
|
||||
#define INPUT_PORT0 0x00 // 输入端口0寄存器
|
||||
#define INPUT_PORT1 0x01 // 输入端口1寄存器 0为低电平(仅支持读取)
|
||||
#define OUTPUT_PORT0 0x02 // 输出端口0寄存器
|
||||
#define OUTPUT_PORT1 0x03 // 输出端口1寄存器 0为低电平
|
||||
#define CONFIG_PORT0 0x04 // 配置端口0寄存器
|
||||
#define CONFIG_PORT1 0x05 // 配置端口1寄存器 0为输出模式
|
||||
#define INT_PORT0 0x06 // 中断端口0寄存器
|
||||
#define INT_PORT1 0x07 // 中断端口1寄存器 0为使能中断(根据手册默认是使能的)
|
||||
#define CTL 0x11 // 全局控制寄存器
|
||||
#define ID 0x23 // 芯片ID寄存器(0x23)
|
||||
|
||||
/***********************************IO扩展板电机引脚配置参数*************************************/
|
||||
/* 设置步进电机方向 */
|
||||
#define STEPPER_MOTOR_LEFT false //步进电机的方向为左转
|
||||
#define STEPPER_MOTOR_RIGHT true //步进电机的方向为右转
|
||||
#define STEPPER_MOTOR_DIR_PORT OUTPUT_PORT0 //步进电机方向引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
|
||||
#define STEPPER_MOTOR_DIR_PIN 4 //步进电机方向引脚对应的IO扩展板引脚P0_4
|
||||
|
||||
/* 设置步进电机细分模式 */
|
||||
#define STEPPER_MOTOR_M0_PIN 5 //步进电机细分模式选择引脚对应IO扩展板引脚P1_5
|
||||
#define STEPPER_MOTOR_M1_PIN 4 //步进电机细分模式选择引脚对应IO扩展板引脚P1_4
|
||||
#define STEPPER_MOTOR_MADE_PORT OUTPUT_PORT1 //步进电机模式选择引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
|
||||
|
||||
|
||||
/* 设置步进电机睡眠引脚 */
|
||||
#define STEPPER_MOTOR_SLEEP false //步进电机进入睡眠模式
|
||||
#define STEPPER_MOTOR_WORK true //步进电机进入工作模式
|
||||
#define STEPPER_MOTOR_SLEEP_PIN 6 //步进电机睡眠引脚对应IO扩展板引脚P1_6
|
||||
#define STEPPER_MOTOR_SLEEP_PORT OUTPUT_PORT1 //步进电机睡眠引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
|
||||
|
||||
/* 设置电机的使能引脚 */
|
||||
#define STEPPER_MOTOR_ENABLE_PIN 7 //电机使能引脚对应IO扩展板引脚P0_7
|
||||
#define STEPPER_MOTOR_ENABLE_PORT OUTPUT_PORT0 //电机使能引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
|
||||
#define STEPPER_MOTOR_ENABLE_ENABLE true //电机使能引脚状态为高电平
|
||||
#define STEPPER_MOTOR_ENABLE_DISABLE false //电机使能引脚状态为低电平
|
||||
|
||||
/* 设置毫米波雷达对应IO扩展板的中断引脚 */
|
||||
#define RADAR_INTERRUPT_PIN 7 //毫米波雷达中断引脚对应IO扩展板引脚P1_7
|
||||
#define RADAR_INTERRUPT_PORT CONFIG_PORT1 //毫米波雷达中断引脚挂载在IO扩展板的输入端口INPUT_PORT1
|
||||
#define RADAR_INTERRUPT_ENABLE true //毫米波雷达中断引脚状态为输入状态
|
||||
#define RADAR_INTERRUPT_DISABLE false //毫米波雷达中断引脚状态为输出状态
|
||||
/* 任务配置常量 */
|
||||
#define WRITE_BUF_SIZE 2 // I2C单次写入字节数
|
||||
#define READ_BUF_SIZE 2 // I2C单次读取字节数
|
||||
#define I2C_TASK_PRIORITY 2 // 任务优先级(中等)
|
||||
#define I2C_TASK_STACK 4096 // 任务栈大小(4KB)
|
||||
|
||||
/***********************************IO扩展板LCD引脚配置参数*************************************/
|
||||
/* 设置LCD的BL引脚 */
|
||||
#define LCD_BL_PIN 6 //LCD背光引脚
|
||||
#define LCD_BL_PORT OUTPUT_PORT0 //LCD背光引脚挂载在IO扩展板的输出端口OUTPUT_PORT0
|
||||
#define LCD_BL_HIGH true //LCD背光引脚状态为高电平
|
||||
#define LCD_BL_LOW false //LCD背光引脚状态为低电平
|
||||
|
||||
/* 设置LCD的RST引脚 */
|
||||
#define LCD_RST_PIN 1 //LCD复位引脚
|
||||
#define LCD_RST_PORT OUTPUT_PORT1 //LCD复位引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
|
||||
#define LCD_RST_HIGH true //LCD复位引脚状态为高电平
|
||||
#define LCD_RST_LOW false //LCD复位引脚状态为低电平
|
||||
|
||||
/* 设置LCD的CS引脚 */
|
||||
#define LCD_CS_PIN 2 //LCD片选引脚
|
||||
#define LCD_CS_PORT OUTPUT_PORT1 //LCD片选引脚挂载在IO扩展板的输出端口OUTPUT_PORT1
|
||||
#define LCD_CS_HIGH true //LCD片选引脚状态为高电平
|
||||
#define LCD_CS_LOW false //LCD片选引脚状态为低电平
|
||||
|
||||
#define TAG_GPIO_IO_EXPAND_DETECT "GPIO_IO_EXPAND_DETECT" // GPIO中断检测日志标签
|
||||
#define TAG_I2C_IO_EXPAND_TASK "I2C_IO_EXPAND_TASK" // I2CIO扩展板任务日志标签
|
||||
|
||||
// GPIO引脚定义
|
||||
#define GPIO_INPUT_PIN_SEL GPIO_NUM_10 // IO扩展板中断检测引脚
|
||||
#define IO_EXPAND_RSTN GPIO_NUM_45 // IO扩展板复位引脚
|
||||
|
||||
/**
|
||||
* @class IOExpansionBoard
|
||||
* @brief I/O扩展板驱动类,封装AW9523BTQR芯片操作
|
||||
*/
|
||||
class IOExpansionBoard
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief 构造函数
|
||||
*/
|
||||
IOExpansionBoard();
|
||||
|
||||
/**
|
||||
* @brief 设置毫米波雷达指针
|
||||
* @param radar 毫米波雷达对象指针
|
||||
*/
|
||||
void setRadar(MillimeterWaveRadar* radar) { radar_ = radar; };
|
||||
|
||||
/**
|
||||
* @brief 析构函数
|
||||
*/
|
||||
~IOExpansionBoard();
|
||||
|
||||
/**
|
||||
* @brief 初始化GPIO中断检测
|
||||
* @param gpio_num 中断引脚编号
|
||||
* @return esp_err_t 初始化结果
|
||||
*/
|
||||
esp_err_t InterruptGpioInit(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief 初始化IO扩展板复位引脚
|
||||
* @param gpio_num 复位引脚编号
|
||||
* @return esp_err_t 初始化结果
|
||||
*/
|
||||
esp_err_t ResetGpioInit(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief 初始化IO扩展板复位引脚
|
||||
* @param gpio_num 复位引脚编号
|
||||
* @return esp_err_t 初始化结果
|
||||
*/
|
||||
esp_err_t ResetIoExpand();
|
||||
|
||||
/**
|
||||
* @brief 初始化I2C主机通信
|
||||
* @return esp_err_t 初始化结果
|
||||
*/
|
||||
// esp_err_t IoExpansionI2cInit();
|
||||
|
||||
/**
|
||||
* @brief 创建I2C数据读取任务
|
||||
*/
|
||||
void CreateI2cReadTask();
|
||||
|
||||
/**
|
||||
* @brief 启动I2C任务(整合初始化和任务创建)
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t StartTask();
|
||||
|
||||
/**
|
||||
* @brief 写寄存器数据
|
||||
* @param reg_addr 寄存器地址
|
||||
* @param data 要写入的数据
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t IoexpandWriteReg(uint8_t reg_addr, uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief 读寄存器数据
|
||||
* @param reg_addr 寄存器地址
|
||||
* @param data 要读出的数据
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t IoexpandReadReg(uint8_t reg_addr, uint8_t *data);
|
||||
|
||||
// /**
|
||||
// * @brief 设置IO扩展板GPIO中断状态 通过读取Input_Port0 和 Input_Port1 寄存器可以清除中断
|
||||
// * @param reg_addr 寄存器地址
|
||||
// * @return esp_err_t 操作结果
|
||||
// */
|
||||
// esp_err_t SetInterruptStatus(bool status);
|
||||
|
||||
/**
|
||||
* @brief 配置IO扩展版上的IO口为输出还是输入,并且设置初始为高电平
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t IoexpandSetMode();
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的细分模式
|
||||
* @param mode 模式:1/2/4/8/16/32/64
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
void SetStepperMicrostepMode(uint8_t mode, uint8_t OUTPUT_PORT, uint8_t m0_pin, uint8_t m1_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的方向
|
||||
* @param dir 方向
|
||||
* @param OUTPUT_PORT 输出端口
|
||||
* @param pin 引脚号
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t StepperMotorSetDir(bool dir, uint8_t OUTPUT_PORT, uint8_t pin);
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的睡眠模式
|
||||
* @param 是否进入睡眠模式
|
||||
* @param 输出端口
|
||||
* @param 引脚号
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetMotorSleepMode(bool mode, uint8_t OUTPUT_PORT, uint8_t nsleep_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置步进电机的使能引脚状态
|
||||
* @param 使能状态
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetMotorEnableMode(bool enable, uint8_t OUTPUT_PORT, uint8_t enable_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置LCD的BL引脚状态
|
||||
* @param BL状态
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetLcdBlMode(bool mode, uint8_t OUTPUT_PORT, uint8_t bl_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置LCD的RST引脚状态
|
||||
* @param RST状态
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetLcdResetMode(bool mode, uint8_t OUTPUT_PORT, uint8_t rst_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置LCD的CS引脚状态
|
||||
* @param CS状态(低电平为选中状态,高电平为不选中状态)
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetLcdCsMode(bool mode, uint8_t OUTPUT_PORT, uint8_t cs_pin);
|
||||
|
||||
/**
|
||||
* @brief 设置雷达中断引脚
|
||||
* @param 毫米波雷达的中断引脚模式
|
||||
* @param 输入端口
|
||||
* @param 引脚号
|
||||
* @return esp_err_t 操作结果
|
||||
*/
|
||||
esp_err_t SetRadarInterruptPin(bool mode, uint8_t INPUT_PORT, uint8_t interrupt_pin);
|
||||
|
||||
// 公共成员变量
|
||||
i2c_bus_handle_t bus_handle_ = nullptr; // I2C总线句柄
|
||||
uint8_t device_addr_; // I2C设备地址
|
||||
|
||||
private:
|
||||
// 静态成员函数
|
||||
MillimeterWaveRadar* radar_ = nullptr; // 毫米波雷达指针,用于触发回调
|
||||
static void IRAM_ATTR GpioIsrHandler(void* arg); // 中断处理函数
|
||||
static void I2cReadTask(void* pvParameters); // I2C数据读取任务函数
|
||||
|
||||
// /**
|
||||
// * @brief 分配静态任务所需的内存
|
||||
// * @return bool 分配是否成功
|
||||
// */
|
||||
// bool AllocateStaticTaskMemory();
|
||||
|
||||
// /**
|
||||
// * @brief 释放静态任务分配的内存
|
||||
// */
|
||||
// void FreeStaticTaskMemory();
|
||||
|
||||
// 实例成员变量
|
||||
EventGroupHandle_t i2c_task_event_group_ = nullptr; // 事件组
|
||||
TaskHandle_t xI2CReadTaskHandle_ = nullptr; // 任务句柄
|
||||
bool is_initialized_ = false; // 初始化状态标记(新增)
|
||||
gpio_num_t interrupt_gpio_ = GPIO_NUM_NC; // 中断引脚
|
||||
gpio_num_t reset_gpio_ = GPIO_NUM_NC; // 复位引脚
|
||||
|
||||
// StackType_t* pI2CReadTaskStackBuffer = nullptr; // 任务栈指针(PSRAM)
|
||||
// StaticTask_t* pxI2CReadTaskBuffer = nullptr; // 任务控制块指针(内部RAM)
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user