Use when diagnosing SPI communication issues with DW3000 on STM32, debugging DEV_ID read failures, or implementing DW3000 SPI platform layer. Triggers on EAMRW errors, 0x00000000/0xFFFFFFFF reads, or CS timing problems.
DW3000 SPI 要求严格的 CS 时序和全双工传输。STM32 HAL 常见误用导致通信失败。
// ✅ 正确:单次调用,CS 保持低电平
uint8_t tx[N], rx[N];
// ... 填充 header + dummy ...
HAL_GPIO_WritePin(CS_Port, CS_Pin, GPIO_PIN_RESET);
HAL_SPI_TransmitReceive(&hspi2, tx, rx, N, timeout);
HAL_GPIO_WritePin(CS_Port, CS_Pin, GPIO_PIN_SET);
// ❌ 错误:拆分传输,CS 中间可能抬起
HAL_SPI_Transmit(&hspi2, header, hlen, timeout);
HAL_SPI_Receive(&hspi2, data, dlen, timeout); // DW3000 EAMRW bit 需要连续
原因:DW3000 Extended Address Mode R/W (EAMRW) 依赖 CS 在整个 header+data 期间保持低电平。HAL_SPI_Transmit 完成后 HAL 可能释放 SPI,导致时序断裂。
decamutex_t stat = decamutexon();
// SPI 操作
decamutexoff(stat);
decamutexon() 禁用 EXTI9_5 NVIC,防止 ISR 中的 SPI 操作与主线程冲突。
decadriver 的 readfromspi / writetospi 使用 VLA(变长数组):
void readfromspi(uint16_t hlen, const uint8_t* hbuf,
uint16_t blen, uint8_t* bbuf) {
uint8_t tx[hlen + blen]; // VLA
uint8_t rx[hlen + blen]; // VLA
// ...
}
确保栈空间充足(默认 STM32 栈通常够用,但超大帧需注意)。
| 读到值 | 根因 | 修复 |
|---|---|---|
0x00000000 | CS 没拉低 / SPI 时钟没输出 / BU03 没供电 | 检查 GPIO 配置和供电 |
0xFFFFFFFF | MISO 悬空(没焊/断线) | 检查 MISO 连接 |
0xDECA0302 | ✅ 正常 (DW3000 C0) | — |
| 随机值 | SPI 模式错误 (CPOL/CPHA) | DW3000 需 SPI Mode 0 (CPOL=0, CPHA=0) |
| 阶段 | 速率 | 说明 |
|---|---|---|
| 初始化 | ≤ 7 MHz | DW3000 INIT_RC 状态限制 |
| 正常运行 | ≤ 38 MHz | IDLE_PLL 后可提速 |
dw3000_spi_speed_slow(); // 初始化前
// ... dwhw_init() ...
dw3000_spi_speed_fast(); // 初始化成功后(由 decadriver 内部切换)
| 症状 | 原因 | 解决 |
|---|---|---|
| dwhw_init() 返回 false | SPI 无应答 | 检查接线 + DEV_ID |
| dwphy_config() 失败 | PLL 锁定超时 | 检查天线/射频供电 |
| dwt_isr() 不执行 | IRQ pin 未接 + 没轮询 | 主循环调 dw3000_hw_process_irq() |
| TX 后无 TXFRS 中断 | SPI 轮询遗漏 | 确保主循环不阻塞 |