The INT pin is pulled down, but sometimes it takes 1 second to interrupt

Hi:

I use ncs 3.3.0 and nrf54lm20dk.

USB mode running phenomenon: Mouse stuttering.

But use ncs 3.1.0 mouse is very smooth.

Since the ncs3.1.0 version does not support nrf54lm20 BLE, I switched to ncs3.3.0.

/*
 * SPDX-License-Identifier: Apache-2.0
 */
#include <zephyr/kernel.h>
#include <stdio.h>
#include <string.h>
#include <nrfx_spim.h>
#include <nrfx_gpiote.h>
#include <hal/nrf_spim.h>
#include <hal/nrf_gpiote.h>
#include "peripheral.h"

/* ------------------------------------------------------------------ */
/*  引脚定义                                                            */
/* ------------------------------------------------------------------ */
#define SCK_PIN    NRF_GPIO_PIN_MAP(1, 11)
#define MOSI_PIN   NRF_GPIO_PIN_MAP(1, 14)
#define MISO_PIN   NRF_GPIO_PIN_MAP(1, 12)
#define CS_PIN     NRF_GPIO_PIN_MAP(1, 10)

/* ------------------------------------------------------------------ */
/*  驱动实例                                                            */
/* ------------------------------------------------------------------ */
// static nrfx_spim_t   spim_inst  = NRFX_SPIM_INSTANCE(21);
// static nrfx_gpiote_t gpiote_inst = NRFX_GPIOTE_INSTANCE(20);
static nrfx_spim_t   *spim_inst;
static nrfx_gpiote_t *gpiote_inst;
/* 传输完成标志 */
static volatile bool spim_xfer_done = false;

/* ------------------------------------------------------------------ */
/*  CS 控制(高电平 = 释放,低电平 = 选中)                              */
/* ------------------------------------------------------------------ */
static inline void cs_assert(void)
{
    /* 拉低 CS,选中从设备 */
    nrfx_gpiote_out_clear(gpiote_inst, CS_PIN);
}

static inline void cs_deassert(void)
{
    /* 拉高 CS,释放从设备 */
    nrfx_gpiote_out_set(gpiote_inst, CS_PIN);
}

/* ------------------------------------------------------------------ */
/*  SPIM 事件回调                                                       */
/* ------------------------------------------------------------------ */
static void spim_event_handler(nrfx_spim_event_t const *p_event,
                                void *p_context)
{
    if (p_event->type == NRFX_SPIM_EVENT_DONE) {
        spim_xfer_done = true;
    }
}

ISR_DIRECT_DECLARE(spim21_direct_isr)
{
    nrfx_spim_irq_handler(spim_inst);
    return 0;
}

ISR_DIRECT_DECLARE(gpiote_20_direct_isr)
{
    nrfx_gpiote_irq_handler(gpiote_inst);
    return 0;
}
/* ------------------------------------------------------------------ */
/*  硬件初始化                                                          */
/* ------------------------------------------------------------------ */
void spi_init(void)
{
    int err;
    gpiote_inst = get_gpiote_inst();
    spim_inst   = get_spim_inst();
    printf("spi gpiote_inst = %p\n", (void*)gpiote_inst);
    /* 1. 连接 IRQ(必须最先,且 CONFIG_GPIO=n 时才有效) */
    IRQ_DIRECT_CONNECT(GPIOTE20_0_IRQn, 4, gpiote_20_direct_isr, 0);
    IRQ_DIRECT_CONNECT(GPIOTE20_1_IRQn, 4, gpiote_20_direct_isr, 0);
    irq_enable(GPIOTE20_0_IRQn);
    irq_enable(GPIOTE20_1_IRQn);
    // /* --- GPIOTE 初始化 --- */
    err = nrfx_gpiote_init(gpiote_inst, NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY);
    if (err) {
        printf("nrfx_gpiote_init failed: 0x%x\n", err);
        return;
    }

    /* --- SPIM 初始化(内部自动注册 IRQ)--- */
    nrfx_spim_config_t spim_config = NRFX_SPIM_DEFAULT_CONFIG(
        SCK_PIN, MOSI_PIN, MISO_PIN,
        NRF_SPIM_PIN_NOT_CONNECTED   /* CS 由 GPIOTE 手动控制 */
    );
    spim_config.frequency = NRFX_MHZ_TO_HZ(1);
    spim_config.mode      = NRF_SPIM_MODE_3;
    spim_config.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST;

    err = nrfx_spim_init(spim_inst, &spim_config, spim_event_handler, NULL);
    if (err) {
        printf("nrfx_spim_init failed: 0x%x\n", err);
        return;
    }

    /* --- 配置 CS 引脚为推挽输出 --- */
    nrfx_gpiote_output_config_t output_config = NRFX_GPIOTE_DEFAULT_OUTPUT_CONFIG;

    err = nrfx_gpiote_output_configure(gpiote_inst,
                                       CS_PIN,
                                       &output_config,
                                       NULL);  /* 不使用 GPIOTE task */
    if (err) {
        printf("nrfx_gpiote_output_configure failed: 0x%x\n", err);
        return;
    }

    IRQ_DIRECT_CONNECT(SERIAL21_IRQn, 4, spim21_direct_isr, 0);
    irq_enable(SERIAL21_IRQn);
    /* 初始化完成后拉高 CS(释放从设备) */
    cs_deassert();
}

void spi_cs_pin(bool enable)
{
    if(enable) {
        cs_assert();  /* 拉低 CS */
    } else {
        cs_deassert();  /* 拉高 CS */
    }
}

/* ------------------------------------------------------------------ */
/*  SPI 写操作                                                          */
/* ------------------------------------------------------------------ */
/**
 * @brief SPI 写数据
 * @param p_tx_buf  发送缓冲区指针
 * @param tx_len    发送字节数
 * @return 0 成功,负值失败
 */
int spi_write(const uint8_t *p_tx_buf, size_t tx_len)
{
    nrfx_spim_xfer_desc_t xfer = {
        .p_tx_buffer = p_tx_buf,
        .tx_length   = tx_len,
        .p_rx_buffer = NULL,    /* 只写,不接收 */
        .rx_length   = 0,
    };

    spim_xfer_done = false;

    int err = nrfx_spim_xfer(spim_inst, &xfer, 0);
    if (err) {
        cs_deassert();
        printf("spi_write xfer failed: 0x%x\n", err);
        return -1;
    }

    /* 等待传输完成 */
    while (!spim_xfer_done) {
        /* 可替换为 RTOS 事件等待,如 k_event_wait() */
    }
    return 0;
}


/* ------------------------------------------------------------------ */
/*  SPI 读操作                                                          */
/* ------------------------------------------------------------------ */
/**
 * @brief SPI 写后等待指定时间再读
 * @param p_tx_buf   发送缓冲区指针(命令/地址)
 * @param tx_len     发送字节数
 * @param p_rx_buf   接收缓冲区指针
 * @param rx_len     接收字节数
 * @param delay_us   写完到读之间的等待时间(微秒)
 * @return 0 成功,负值失败
 */
int spi_read(uint8_t *p_rx_buf,       size_t rx_len)
{
    int err;

    /* ---- 第三步:读 ---- */
    nrfx_spim_xfer_desc_t xfer_rx = {
        .p_tx_buffer = NULL,
        .tx_length   = 0,
        .p_rx_buffer = p_rx_buf,
        .rx_length   = rx_len,
    };

    spim_xfer_done = false;

    err = nrfx_spim_xfer(spim_inst, &xfer_rx, 0);
    if (err) {
        cs_deassert();
        printf("spi_read phase failed: 0x%x\n", err);
        return -1;
    }

    /* 等待读传输完成 */
    while (!spim_xfer_done) {
    }

    //cs_deassert();  /* 拉高 CS */
    return 0;
}

#include <zephyr/kernel.h>
#include <stdio.h>
#include <hal/nrf_egu.h>
#include <nrfx_gpiote.h>
#include <hal/nrf_gpiote.h>
#include "spi.h"
#include "pmw3360.h"
#include "../main.h"
#include "../peripheral/peripheral.h"
#include "../peripheral/timer.h"
#include "../rf/rf_module.h"
#if CONFIG_USBD_HID_SUPPORT
#include "../usb/usb_module.h"
#endif

enum state {
	STATE_IDLE,
    STATE_MOTION,
};

/* 线程参数 */
#define PMW3360_THREAD_STACK_SIZE  1024
#define PMW3360_THREAD_PRIORITY    5

#define SPI_WRITE_BIT                   0x80
#define PMW3360_MOTION_BURST_SIZE       6
#define PMW3360_DX_POS                  2
#define PMW3360_DY_POS                  4

/* ========== 添加时序定义 ========== */
/* Timings defined by spec (from original driver) */
#define T_NCS_SCLK      1               /* 120 ns - CS建立/保持时间 */
#define T_SRX           (20 - T_NCS_SCLK)  /* 20 us - 读操作后的CS释放时间 */
#define T_SCLK_NCS_WR   (35 - T_NCS_SCLK)  /* 35 us - 写操作等待时间 */
#define T_SWX           (180 - T_SCLK_NCS_WR) /* 180 us - 写操作后的处理时间 */
#define T_SRAD          160             /* 160 us - 地址到数据读取延迟 */
#define T_SRAD_MOTBR    35              /* 35 us - 运动突发读取的地址延迟 */
#define T_BEXIT         1               /* 500 ns - 突发模式退出时间 */
#define T_BRSEP         15              /* 15 us - SROM突发写入字节间隔 */


#define RING_BUF_SIZE (32 * sizeof(motion_data_t))
RING_BUF_DECLARE(motion_ring_buf, RING_BUF_SIZE);

/* 全局事件对象 */
static nrfx_gpiote_t *gpiote_inst;
struct k_event pmw3360_event;
static bool initialized = false;
static bool last_read_burst = false;
static enum state state = STATE_IDLE;
K_MUTEX_DEFINE(pmw3360_mutex);
/* 固件数据(需要从外部文件引入) */
extern const size_t pmw3360_firmware_length;
extern const uint8_t pmw3360_firmware_data[];


/* --- 中断回调函数 --- */
static void gpiote_evt_handler(nrfx_gpiote_pin_t pin,
                               nrfx_gpiote_trigger_t trigger,
                               void *p_context)
{
    //printf("Interrupt on pin %d\n", pin);
    /* 使用 k_uptime_get() 手动添加时间戳 */
    //printf("[%lld ms] Interrupt pin\n", k_uptime_get());
    pmw3360_irq_disable();
    k_event_post(&pmw3360_event, PMW3360_EVENT_DATA_READY);
}

static void pmw3360_irq_init(void)
{
    int err;

    /* 添加 static const,确保生命周期贯穿整个运行时 */
    static const nrf_gpio_pin_pull_t pull_config = NRF_GPIO_PIN_PULLUP;

    static const nrfx_gpiote_trigger_config_t trigger_config = {
        .trigger      = NRFX_GPIOTE_TRIGGER_LOW,
        .p_in_channel = NULL,
    };

    static const nrfx_gpiote_handler_config_t handler_config = {
        .handler   = gpiote_evt_handler,
        .p_context = NULL,
    };

    static const nrfx_gpiote_input_pin_config_t input_pin_config = {
        .p_pull_config    = &pull_config,
        .p_trigger_config = &trigger_config,
        .p_handler_config = &handler_config,
    };

    err = nrfx_gpiote_input_configure(gpiote_inst,
                                      IRQ_PIN,
                                      &input_pin_config);
    if (err) {
        printf("nrfx_gpiote_input_configure failed: 0x%x\n", err);
        return;
    }
}

void pmw3360_irq_enable(void)
{
    /* 中断使能代码... */
    //printf("[%lld ms] Interrupt enable\n", k_uptime_get());
    nrfx_gpiote_trigger_enable(gpiote_inst, IRQ_PIN, true);
    // 重新使能后检查引脚是否仍为低电平
    if (nrf_gpio_pin_read(IRQ_PIN) == 0) {
        // 引脚仍为低,手动补发事件
        k_event_post(&pmw3360_event, PMW3360_EVENT_DATA_READY);
    }
}

void pmw3360_irq_disable(void)
{
    nrfx_gpiote_trigger_disable(gpiote_inst, IRQ_PIN);
}

/* ========== 辅助函数:CS控制 ========== */
static int spi_cs_ctrl(bool enable)
{
    /* 根据你的硬件实现CS控制 */
    if (!enable) {
        k_busy_wait(T_NCS_SCLK);  /* 延迟1: CS释放前的建立时间 */
    }
    
    /* 实际的CS控制代码... */
    spi_cs_pin(enable);
    
    if (enable) {
        k_busy_wait(T_NCS_SCLK);  /* 延迟2: CS使能后的保持时间 */
    }
    
    return 0;
}

/* PMW3360读寄存器 - 添加时序延迟 */
static int pmw3360_reg_read(uint8_t reg, uint8_t *value)
{
    //uint8_t tx[2] = {reg, *value};
    uint8_t tx = reg;
    
    /* 延迟3: 开始传输前确保CS已建立 */
    spi_cs_ctrl(true);  /* 内部会有T_NCS_SCLK延迟 */
    
    spi_write(&tx, 1);
    
    /* 延迟4: 地址发送后到读取数据的等待时间 T_SRAD (160 us) */
    k_busy_wait(T_SRAD);  /* 关键延迟:等待传感器准备数据 */
    
    spi_read(value, 1);
    
    /* 延迟5: 结束传输后的CS释放时间 T_SRX (20 us) */
    spi_cs_ctrl(false);  /* 内部会有T_SRX延迟 */
    k_busy_wait(T_SRX);
    
    /* 清除突发读取标志 */
    last_read_burst = false;
    return 0;
}

/* PMW3360写寄存器 - 添加时序延迟 */
static int pmw3360_reg_write(uint8_t reg, uint8_t value)
{
    uint8_t tx[2] = {SPI_WRITE_BIT | reg, value};
    
    /* 延迟6: 开始传输前确保CS已建立 */
    spi_cs_ctrl(true);
    
    spi_write(tx, 2);
    
    /* 延迟7: 写入完成后的等待时间 T_SCLK_NCS_WR (35 us) */
    k_busy_wait(T_SCLK_NCS_WR);
    
    spi_cs_ctrl(false);
    
    /* 延迟8: 写操作后的处理时间 T_SWX (180 us) */
    k_busy_wait(T_SWX);  /* 关键延迟:传感器处理写入命令 */

    /* 清除突发读取标志 */
    last_read_burst = false;
    return 0;
}

/* PMW3360突发写(用于固件上传)- 单字节发送方式 */
static int pmw3360_burst_write(uint8_t reg, const uint8_t *data, size_t len)
{
    int ret = 0;
    uint8_t buf;
    if (data == NULL || len == 0) {
        printf("Error: Invalid data or length\n");
        return -1;
    }
    
    printf("fw length = %zu\n", len);
    
    /* 延迟: 突发模式开始前的CS建立 */
    spi_cs_ctrl(true);
    
    /* 第一步:发送寄存器地址(第一个字节) */
    uint8_t reg_byte = SPI_WRITE_BIT | reg;
    spi_write(&reg_byte, 1);
    
    /* 延迟:字节间隔 T_BRSEP (15 us) */
    k_busy_wait(T_BRSEP);
    
    printf("pmw3360_firmware_data\n");
    /* 第二步:逐个发送固件数据字节 */
    for (size_t i = 0; i < len; i++) {
        buf = data[i];
        /* 发送一个字节 */
        spi_write(&buf, 1);
        
        /* 每个字节后延迟 T_BRSEP (15 us) */
        /* 注意:最后一个字节后也需要延迟 */
        k_busy_wait(T_BRSEP);
        
        /* 可选:每发送一定字节数打印进度 */
        // if ((i + 1) % 512 == 0) {
        //     printf("FW progress: %zu/%zu bytes\n", i + 1, len);
        // }
    }
    
    /* 延迟: 突发模式退出时间 T_BEXIT (500 ns) */
    spi_cs_ctrl(false);
    k_busy_wait(T_BEXIT);

    last_read_burst = false;
    
    printf("FW upload complete: %zu bytes\n", len);
    
    return ret;
}

int pmw3360_motion_burst_read(int16_t *dx, int16_t *dy)
{
    uint8_t tx;
    uint8_t rx[PMW3360_MOTION_BURST_SIZE];
    int err;
    
    /* ============================================================
     * 步骤1: 触发突发模式(仅在需要时)
     * ============================================================ */
    if (!last_read_burst) {
        /* 只有上次不是突发读取时,才需要写入触发命令 */
        err = pmw3360_reg_write(PMW3360_REG_MOTION_BURST, 0x00);
        if (err) {
            printf("Failed to trigger motion burst\n");
            return err;
        }
        /* reg_write 内部已经包含了:
         * - CS控制 (拉低→写→拉高)
         * - T_SCLK_NCS_WR (35us)
         * - T_SWX (180us)
         */
    }
    
    /* ============================================================
     * 步骤2: 读取突发数据
     * ============================================================ */
    /* 2.1 CS拉低,开始SPI传输 */
    spi_cs_ctrl(true);
    
    /* 2.2 发送突发读取地址 (0x50) */
    tx = PMW3360_REG_MOTION_BURST;
    spi_write(&tx, 1);
    
    /* 2.3 关键延迟:等待传感器准备数据 (35us) */
    /* 注意:这个延迟必须在地址发送之后、数据读取之前 */
    k_busy_wait(T_SRAD_MOTBR);
    
    /* 2.4 连续读取6个字节 */
    /* 注意:读取时发送0xFF来产生SPI时钟 */
    // for (int i = 0; i < PMW3360_MOTION_BURST_SIZE; i++) {
    //     uint8_t dummy = 0xFF;
    //     spi_read(&rx[i], 1);
    //     /* 如果SPI是半双工,可以分开操作:
    //      * spi_write(&dummy, 1);
    //      * spi_read(&rx[i], 1);
    //      */
    // }
    spi_read(rx, PMW3360_MOTION_BURST_SIZE);
    /* 2.5 结束SPI传输 */
    spi_cs_ctrl(false);
    k_busy_wait(T_BEXIT);
    
    /* ============================================================
     * 步骤3: 标记已完成突发读取
     * ============================================================ */
    last_read_burst = true;
    
    /* ============================================================
     * 步骤4: 解析数据
     * ============================================================ */
    if (dx && dy) {
        /* 注意:PMW3360的数据是小端格式 */
        *dx = (int16_t)((rx[PMW3360_DX_POS + 1] << 8) | rx[PMW3360_DX_POS]);
        *dy = (int16_t)((rx[PMW3360_DY_POS + 1] << 8) | rx[PMW3360_DY_POS]);
        
        /* 可选:数据有效性检查 */
        /* PMW3360运动数据范围通常是 -32768 ~ 32767 */
        /* 如果dx和dy都为0,可能表示静止或读取失败 */
    }
    
    return 0;
}

static int pmw3360_upload_firmware(void)
{
    int err;
    uint8_t val;
    
    printf("Uploading PMW3360 firmware...\n");
    
    /* 读取运动寄存器清除状态 */
    for (uint8_t reg = 0x02; reg <= 0x06; reg++) {
        pmw3360_reg_read(reg, &val);
    }

    /* 禁用Rest模式 */
    pmw3360_reg_write(PMW3360_REG_CONFIG2, 0x00);
    
    /* 初始化SROM */
    pmw3360_reg_write(PMW3360_REG_SROM_ENABLE, 0x1D);
    
    /* 延迟17: 等待SROM初始化完成 (50 ms) */
    k_sleep(K_MSEC(10));  /* 关键延迟:固件加载前的准备时间 */
    
    /* 开始SROM下载 */
    pmw3360_reg_write(PMW3360_REG_SROM_ENABLE, 0x18);
    
    /* 上传固件 */
    //printf("PMW3360_REG_SROM_LOAD_BURST fw=%d\n", pmw3360_firmware_length);
    pmw3360_burst_write(PMW3360_REG_SROM_LOAD_BURST,
                               pmw3360_firmware_data,
                               pmw3360_firmware_length);
    
    /* 延迟18: 等待固件加载完成 (10 ms) */
    k_sleep(K_MSEC(10));  /* 关键延迟:固件验证前的等待时间 */
    
    /* 验证固件ID */
    err = pmw3360_reg_read(PMW3360_REG_SROM_ID, &val);
    if (err) return err;
    
    printf("Firmware ID: 0x%02X (expected: 0x%02X)\n", val, PMW3360_FIRMWARE_ID);
    if (val != PMW3360_FIRMWARE_ID) {
        printf("Invalid firmware ID\n");
        return -EIO;
    }
    
    /* 验证产品ID */
    err = pmw3360_reg_read(PMW3360_REG_PRODUCT_ID, &val);
    if (err) return err;
    
    if (val != PMW3360_PRODUCT_ID) {
        printf("Invalid product ID: 0x%02X\n", val);
        return -EIO;
    }
    
    /* 启用Rest模式 */
    err = pmw3360_reg_write(PMW3360_REG_CONFIG2, 0x20);
    if (err) return err;
    
    printf("Firmware upload successful\n");
    return 0;
}

/* ==================== PMW3360 配置 ==================== */

static int pmw3360_configure(uint32_t cpi)
{
    uint8_t value;
    
    /* 设置CPI */
    if (cpi < 100 || cpi > 12000) {
        printf("Invalid CPI value: %u\n", cpi);
        return -EINVAL;
    }
    
    value = (cpi / 100) - 1;
    pmw3360_reg_write(PMW3360_REG_CONFIG1, value);

    /* 2. ? 禁用Rest模式,强制Run模式(最高帧率) */
    pmw3360_reg_write(PMW3360_REG_CONFIG2, 0x00);

    printf("PMW3360 configured: CPI=%u, Rest mode disabled (always Run)\n", cpi);
    return 0;
}

/* 初始化PMW3360 */
int pmw3360_init(uint32_t cpi)
{
    int err;

    gpiote_inst = get_gpiote_inst();
    printf("pmw3xx gpiote_inst = %p\n", (void*)gpiote_inst);
    pmw3360_irq_init();   /* 初始化运动中断 */
    
    printf("pmw3360_irq_init\n");
    
    /* 复位传感器 */
    err = pmw3360_reg_write(PMW3360_REG_POWER_UP_RESET, 0x5A);
    printf("pmw3360_reg_write err=%d\n", err);
    if (err) {
        printf("Reset failed. err=%d\n", err);
        return err;
    }
    
    /* 延迟19: 复位后等待传感器稳定 (1 ms) */
    k_sleep(K_MSEC(50));  /* 关键延迟:上电复位后的稳定时间 */
    
    /* 上传固件 */
    err = pmw3360_upload_firmware();
    if (err) {
        printf("Firmware upload failed. err=%d\n", err);
        return err;
    }
    
    /* 配置传感器 */
    err = pmw3360_configure(cpi);
    if (err) {
        printf("Configuration failed. err=%d\n", err);
    }
    
    initialized = true;
    printf("PMW3360 initialized (CPI=%u)\n", cpi);
    
    nrfx_gpiote_trigger_enable(gpiote_inst, IRQ_PIN, true);
    return 0;
}

/* 线程入口函数 */
void pmw3360_thread(void *p1, void *p2, void *p3)
{
    int err;
    enum state new_state = STATE_IDLE;
    int16_t dx=0,dy=0;
    k_event_init(&pmw3360_event);
    spi_init();
    err = pmw3360_init(1600);
    //pmw3360_irq_enable();
    while (1) {
        /* 替代 k_event_wait_safe */
        uint32_t events = k_event_wait(&pmw3360_event,
                                       PMW3360_EVENT_DATA_READY,
                                       false,        /* reset=false */
                                       K_FOREVER);//K_MSEC(200)
        //if (events & PMW3360_EVENT_DATA_READY) 
        {
            bool is_timed_tx = (atomic_get(&ptx_delay) > 0);
            if(!is_timed_tx) {
                pmw3360_motion_burst_read(&dx, &dy);
            } else {
                dx = 1;
                dy = 1;
                start_motion_idle_timer();
            }
            
            /* 手动原子清除,紧接在判断之后 */
            k_event_clear(&pmw3360_event, PMW3360_EVENT_DATA_READY);
            //printf("PMW3360: dx=%d,dy=%d\n",dx,dy);
#if CONFIG_USBD_HID_SUPPORT
            //printf("rf status=%d.\n", rf_motion_status());
            // 如果是定时发送,且(USB有动作 或 RF有动作),则跳过
            if (is_timed_tx && (usb_motion_status())) { //|| rf_motion_status()
#else 
            if (is_timed_tx && rf_motion_status()) {
#endif
                pmw3360_irq_enable();
                continue;
            }                       
            /* 只有有实际运动时才写入,减少无效数据 */
            if (dx != 0 || dy != 0) {
                motion_data_t data = { .dx = dx, .dy = dy };
                //printf("[%lld ms] mutex_lock\n", k_uptime_get());
                k_mutex_lock(&pmw3360_mutex, K_FOREVER);
                uint32_t written = ring_buf_put(&motion_ring_buf,
                                                (uint8_t *)&data,
                                                sizeof(data));
                k_mutex_unlock(&pmw3360_mutex);
                //printf("[%lld ms] mutex_unlock\n", k_uptime_get());
                if (written == sizeof(data)) {
                    //new_state = STATE_MOTION;
                    struct main_msg msg;
                    msg.type = MAIN_MSG_MOTION;
                    msg.cnt = 1;
                    int err = k_msgq_put(&main_msgq, &msg, K_NO_WAIT);
                    if (err) {
                        printf("Cannot put button event to message queue: %d\n", err);
                    }
                } else {
                    /* 缓冲区满,可在此记录溢出或丢弃 */
                    printf("ring buf full, data dropped\n");
                }
            }
        }
        pmw3360_irq_enable();
    }
}

/* 编译时定义并启动线程 */
K_THREAD_DEFINE(pmw3360_tid,
                PMW3360_THREAD_STACK_SIZE,
                pmw3360_thread,
                NULL, NULL, NULL,
                PMW3360_THREAD_PRIORITY,
                0,
                0);  /* delay=0,立即启动 */

Related