123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- #pragma once
- #include "driver/gpio.h"
- #include "driver/i2c_master.h"
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "esp_log.h"
- #define TAG1 "SC7660"
- // SC7660寄存器地址
- #define SC7660_ADDR 0x19 // 假设I2C地址为0x19,请根据实际硬件确认
- #define SC7660_CTRL_REG0 0x1F
- #define SC7660_CTRL_REG1 0x20
- #define SC7660_CTRL_REG2 0x21
- #define SC7660_CTRL_REG3 0x22
- #define SC7660_CTRL_REG4 0x23
- #define SC7660_CTRL_REG5 0x24
- #define SC7660_CTRL_REG6 0x25
- #define SC7660_CLICK_CFG 0x38
- #define SC7660_CLICK_SRC 0x39
- #define SC7660_CLICK_THS 0x3A
- #define SC7660_TIME_LIMIT 0x3B
- #define SC7660_TIME_LATENCY 0x3C
- #define SC7660_TIME_WINDOW 0x3D
- #define SC7660_INT1_CFG 0x30
- #define SC7660_INT1_THS 0x32
- #define SC7660_INT1_DURATION 0x33
- #define SC7660_STATUS_REG 0x27
- #define SC7660_OUT_X_L 0x28
- #define SC7660_OUT_X_H 0x29
- #define SC7660_OUT_Y_L 0x2A
- #define SC7660_OUT_Y_H 0x2B
- #define SC7660_OUT_Z_L 0x2C
- #define SC7660_OUT_Z_H 0x2D
- #define SC7660_CTRL_REG58 58
- // 中断引脚配置
- #define SC7660_INT1_GPIO GPIO_NUM_9
- class SC7660Driver {
- private:
- i2c_master_dev_handle_t dev_handle;
- // QueueHandle_t interrupt_queue;
-
- esp_err_t write_register(uint8_t reg, uint8_t value) {
- uint8_t write_buf[2] = {reg, value};
- return i2c_master_transmit(dev_handle, write_buf, sizeof(write_buf), -1);
- }
-
- esp_err_t read_register(uint8_t reg, uint8_t *value) {
- esp_err_t ret = i2c_master_transmit(dev_handle, ®, 1, -1);
- if (ret != ESP_OK) return ret;
- return i2c_master_receive(dev_handle, value, 1, -1);
- }
-
- esp_err_t read_registers(uint8_t reg, uint8_t *data, size_t len) {
- esp_err_t ret = i2c_master_transmit(dev_handle, ®, 1, -1);
- if (ret != ESP_OK) return ret;
- return i2c_master_receive(dev_handle, data, len, -1);
- }
- public:
- SC7660Driver(i2c_master_bus_handle_t bus_handle) {
- i2c_device_config_t dev_cfg = {
- .dev_addr_length = I2C_ADDR_BIT_LEN_7,
- .device_address = SC7660_ADDR,
- .scl_speed_hz = 400000, // 400kHz
- };
-
- ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
-
- // 创建中断队列
- // interrupt_queue = xQueueCreate(10, sizeof(uint32_t));
- }
-
- ~SC7660Driver() {
- i2c_master_bus_rm_device(dev_handle);
- //vQueueDelete(interrupt_queue);
- }
-
- esp_err_t init() {
- ESP_LOGI(TAG1, "Initializing SC7660...");
-
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG0, 0x08));
-
- // 1. 进入掉电模式进行配置
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG1, 0x47));
-
- // 2. 配置双击检测参数(基于文档7.5节示例)
- // 设置ODR为25Hz,使能XYZ轴
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG4, 0x88));
-
- // 配置高通滤波器(作用于CLICK功能)
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG2, 0x31));
-
- // 设置量程为±2G,BDU=1
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG3, 0x40));
-
- // 使能X和Y轴的双击检测
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG6, 0x00));
-
- // 设置点击阈值
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG5, 0x00));
-
- // 设置时间限制窗口
- ESP_ERROR_CHECK(write_register(SC7660_INT1_CFG, 0x2A));
-
- // 设置中断持续时间
- ESP_ERROR_CHECK(write_register(SC7660_INT1_THS, 0x03));
-
- // 设置双击时间窗口
- ESP_ERROR_CHECK(write_register(SC7660_INT1_DURATION, 0x50));
-
- // 3. 配置中断
- // 将双击中断映射到INT1引脚
- ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG58, 0x02));
-
-
- ESP_LOGI(TAG1, "SC7660 initialization complete");
- return ESP_OK;
- }
-
- // esp_err_t setup_interrupt() {
- // // 配置GPIO9为输入,用于接收INT1中断
- // gpio_config_t io_conf = {
- // .pin_bit_mask = (1ULL << SC7660_INT1_GPIO),
- // .mode = GPIO_MODE_INPUT,
- // .pull_up_en = GPIO_PULLUP_DISABLE,
- // .pull_down_en = GPIO_PULLDOWN_DISABLE,
- // .intr_type = GPIO_INTR_POSEDGE, // 上升沿触发
- // };
- // ESP_ERROR_CHECK(gpio_config(&io_conf));
-
- // // 安装GPIO ISR服务
- // ESP_ERROR_CHECK(gpio_install_isr_service(0));
-
- // // 添加ISR处理程序
- // ESP_ERROR_CHECK(gpio_isr_handler_add(SC7660_INT1_GPIO, interrupt_handler, this));
-
- // return ESP_OK;
- // }
-
- // static void IRAM_ATTR interrupt_handler(void* arg) {
- // SC7660Driver* driver = (SC7660Driver*)arg;
- // uint32_t gpio_num = SC7660_INT1_GPIO;
- // xQueueSendFromISR(driver->interrupt_queue, &gpio_num, NULL);
- // }
-
- // void handle_interrupts() {
- // uint32_t io_num;
- // while (xQueueReceive(interrupt_queue, &io_num, portMAX_DELAY)) {
- // if (io_num == SC7660_INT1_GPIO) {
- // // 唤醒设备
- // ESP_LOGI(TAG1, "weak up.");
- // }
- // }
- // }
-
- // // 任务函数
- // static void interrupt_task(void* arg) {
- // SC7660Driver* driver = (SC7660Driver*)arg;
- // driver->handle_interrupts();
- // }
-
- // esp_err_t start_interrupt_handler() {
- // return xTaskCreate(interrupt_task, "sc7660_int", 2048, this, 5, NULL) == pdPASS ? ESP_OK : ESP_FAIL;
- // }
- };
|