feat(device): SPI OTA模块改用DMA发送替代TBE中断

SPI OTA模块从PendSV延迟响应模式改为DMA发送模式,主要改进包括:

- 添加DMA支持,使用DMA0_CH2自动发送SPI0数据,消除字节错位问题
- EXTI ISR直接完成帧校验+处理+响应准备,不再依赖PendSV
- 移除PendSV相关代码和中断处理函数
- CS释放后直接处理帧数据,响应帧写入s_txBuf由DMA自动发送
- 更新注释文档说明新的工作流程和DMA通道映射关系
This commit is contained in:
cbb
2026-05-26 02:44:25 +08:00
parent 747fc56886
commit d1beb3b615
5 changed files with 185 additions and 146 deletions
+10 -15
View File
@@ -5,11 +5,11 @@
/**
* @file SpiOta.h
* @brief SPI OTA 从机协议头文件(PendSV 延迟响应版)。
* @brief SPI OTA 从机协议头文件(ISR 直接响应版)。
*
* CS 释放后,EXTI ISR 只做轻量校验(SOF + LEN + CRC),
* 校验通过则触发 PendSV(最低优先级 ISR),由 PendSV 调用
* handleLinkMessage 完成帧处理和响应准备。
* CS 释放后,EXTI ISR 直接完成帧校验+处理+响应准备,
* 响应帧在 ISR 中写入 s_txBuf,下次 CS 拉低时 DMA 自动发出。
* 无需 TBE 中断,DMA 硬件逐字节推到 MISO,消除字节错位问题。
*/
typedef enum {
@@ -36,6 +36,7 @@ public:
static void onCsRelease();
static void configureGpio();
static void configureSpi0();
static void configureDma();
static void configureExti();
static void onSpiInterrupt();
static void onCsExtiInterrupt();
@@ -43,14 +44,12 @@ public:
static bool hasTxFrame();
static u16 copyTxFrame(u8 *out, u16 max_len);
/** @brief EXTI ISR 内轻量校验,通过则触发 PendSV。 */
static void isrValidateAndPend();
/** @brief PendSV ISR 内执行帧处理和响应准备。 */
static void onPendSvProcess();
/** @brief CS 释放后 ISR 中直接完成帧校验+处理+响应准备。 */
static void isrProcessFrame();
/** @brief ISR 内轻量日志写入延迟打印缓冲。 */
static void isrLogFrame(const char *tag, const u8 *data, u16 len);
/* ---- PendSV 需要访问的成员放 public ---- */
/* ---- 公开成员 ---- */
static OTAHandler *s_otaHandler;
static volatile bool s_csActive;
static volatile u16 s_rxStreamLen;
@@ -59,10 +58,10 @@ public:
static u8 s_txBuf[kTxBufSize];
static volatile u16 s_txLen;
static volatile bool s_txPending;
static volatile bool s_isrResponded; // ISR 已发送响应帧,主循环本轮不再发 WAIT
static volatile bool s_isrLogPending;
static u8 s_isrLogBuf[kIsrLogBufSize];
static u16 s_isrLogLen;
static volatile bool s_pendSVPending;
private:
static u8 crc8(const u8 *data, u16 len);
@@ -83,10 +82,6 @@ private:
extern "C" {
#endif
/**
* 引脚约定:CS=PA15, SCK=PB3, MISO=PB4, MOSI=PB5
*/
void spi_ota_init(void);
void spi_ota_poll(void);
void spi_ota_set_sender(OTAHandler *handler);
@@ -105,4 +100,4 @@ u16 spi_ota_copy_tx_frame(u8 *out, u16 max_len);
}
#endif
#endif
#endif