sc7a20h.h 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #pragma once
  2. #include "driver/gpio.h"
  3. #include "driver/i2c_master.h"
  4. #include "freertos/FreeRTOS.h"
  5. #include "freertos/task.h"
  6. #include "freertos/queue.h"
  7. #include "esp_log.h"
  8. #define TAG1 "SC7660"
  9. // SC7660寄存器地址
  10. #define SC7660_ADDR 0x19 // 假设I2C地址为0x19,请根据实际硬件确认
  11. #define SC7660_CTRL_REG0 0x1F
  12. #define SC7660_CTRL_REG1 0x20
  13. #define SC7660_CTRL_REG2 0x21
  14. #define SC7660_CTRL_REG3 0x22
  15. #define SC7660_CTRL_REG4 0x23
  16. #define SC7660_CTRL_REG5 0x24
  17. #define SC7660_CTRL_REG6 0x25
  18. #define SC7660_CLICK_CFG 0x38
  19. #define SC7660_CLICK_SRC 0x39
  20. #define SC7660_CLICK_THS 0x3A
  21. #define SC7660_TIME_LIMIT 0x3B
  22. #define SC7660_TIME_LATENCY 0x3C
  23. #define SC7660_TIME_WINDOW 0x3D
  24. #define SC7660_INT1_CFG 0x30
  25. #define SC7660_INT1_THS 0x32
  26. #define SC7660_INT1_DURATION 0x33
  27. #define SC7660_STATUS_REG 0x27
  28. #define SC7660_OUT_X_L 0x28
  29. #define SC7660_OUT_X_H 0x29
  30. #define SC7660_OUT_Y_L 0x2A
  31. #define SC7660_OUT_Y_H 0x2B
  32. #define SC7660_OUT_Z_L 0x2C
  33. #define SC7660_OUT_Z_H 0x2D
  34. #define SC7660_CTRL_REG58 58
  35. // 中断引脚配置
  36. #define SC7660_INT1_GPIO GPIO_NUM_9
  37. class SC7660Driver {
  38. private:
  39. i2c_master_dev_handle_t dev_handle;
  40. // QueueHandle_t interrupt_queue;
  41. esp_err_t write_register(uint8_t reg, uint8_t value) {
  42. uint8_t write_buf[2] = {reg, value};
  43. return i2c_master_transmit(dev_handle, write_buf, sizeof(write_buf), -1);
  44. }
  45. esp_err_t read_register(uint8_t reg, uint8_t *value) {
  46. esp_err_t ret = i2c_master_transmit(dev_handle, &reg, 1, -1);
  47. if (ret != ESP_OK) return ret;
  48. return i2c_master_receive(dev_handle, value, 1, -1);
  49. }
  50. esp_err_t read_registers(uint8_t reg, uint8_t *data, size_t len) {
  51. esp_err_t ret = i2c_master_transmit(dev_handle, &reg, 1, -1);
  52. if (ret != ESP_OK) return ret;
  53. return i2c_master_receive(dev_handle, data, len, -1);
  54. }
  55. public:
  56. SC7660Driver(i2c_master_bus_handle_t bus_handle) {
  57. i2c_device_config_t dev_cfg = {
  58. .dev_addr_length = I2C_ADDR_BIT_LEN_7,
  59. .device_address = SC7660_ADDR,
  60. .scl_speed_hz = 400000, // 400kHz
  61. };
  62. ESP_ERROR_CHECK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
  63. // 创建中断队列
  64. // interrupt_queue = xQueueCreate(10, sizeof(uint32_t));
  65. }
  66. ~SC7660Driver() {
  67. i2c_master_bus_rm_device(dev_handle);
  68. //vQueueDelete(interrupt_queue);
  69. }
  70. esp_err_t init() {
  71. ESP_LOGI(TAG1, "Initializing SC7660...");
  72. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG0, 0x08));
  73. // 1. 进入掉电模式进行配置
  74. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG1, 0x47));
  75. // 2. 配置双击检测参数(基于文档7.5节示例)
  76. // 设置ODR为25Hz,使能XYZ轴
  77. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG4, 0x88));
  78. // 配置高通滤波器(作用于CLICK功能)
  79. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG2, 0x31));
  80. // 设置量程为±2G,BDU=1
  81. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG3, 0x40));
  82. // 使能X和Y轴的双击检测
  83. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG6, 0x00));
  84. // 设置点击阈值
  85. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG5, 0x00));
  86. // 设置时间限制窗口
  87. ESP_ERROR_CHECK(write_register(SC7660_INT1_CFG, 0x2A));
  88. // 设置中断持续时间
  89. ESP_ERROR_CHECK(write_register(SC7660_INT1_THS, 0x03));
  90. // 设置双击时间窗口
  91. ESP_ERROR_CHECK(write_register(SC7660_INT1_DURATION, 0x50));
  92. // 3. 配置中断
  93. // 将双击中断映射到INT1引脚
  94. ESP_ERROR_CHECK(write_register(SC7660_CTRL_REG58, 0x02));
  95. ESP_LOGI(TAG1, "SC7660 initialization complete");
  96. return ESP_OK;
  97. }
  98. // esp_err_t setup_interrupt() {
  99. // // 配置GPIO9为输入,用于接收INT1中断
  100. // gpio_config_t io_conf = {
  101. // .pin_bit_mask = (1ULL << SC7660_INT1_GPIO),
  102. // .mode = GPIO_MODE_INPUT,
  103. // .pull_up_en = GPIO_PULLUP_DISABLE,
  104. // .pull_down_en = GPIO_PULLDOWN_DISABLE,
  105. // .intr_type = GPIO_INTR_POSEDGE, // 上升沿触发
  106. // };
  107. // ESP_ERROR_CHECK(gpio_config(&io_conf));
  108. // // 安装GPIO ISR服务
  109. // ESP_ERROR_CHECK(gpio_install_isr_service(0));
  110. // // 添加ISR处理程序
  111. // ESP_ERROR_CHECK(gpio_isr_handler_add(SC7660_INT1_GPIO, interrupt_handler, this));
  112. // return ESP_OK;
  113. // }
  114. // static void IRAM_ATTR interrupt_handler(void* arg) {
  115. // SC7660Driver* driver = (SC7660Driver*)arg;
  116. // uint32_t gpio_num = SC7660_INT1_GPIO;
  117. // xQueueSendFromISR(driver->interrupt_queue, &gpio_num, NULL);
  118. // }
  119. // void handle_interrupts() {
  120. // uint32_t io_num;
  121. // while (xQueueReceive(interrupt_queue, &io_num, portMAX_DELAY)) {
  122. // if (io_num == SC7660_INT1_GPIO) {
  123. // // 唤醒设备
  124. // ESP_LOGI(TAG1, "weak up.");
  125. // }
  126. // }
  127. // }
  128. // // 任务函数
  129. // static void interrupt_task(void* arg) {
  130. // SC7660Driver* driver = (SC7660Driver*)arg;
  131. // driver->handle_interrupts();
  132. // }
  133. // esp_err_t start_interrupt_handler() {
  134. // return xTaskCreate(interrupt_task, "sc7660_int", 2048, this, 5, NULL) == pdPASS ? ESP_OK : ESP_FAIL;
  135. // }
  136. };