#ifndef DEVICE_APP_SPI_COMMAND_H #define DEVICE_APP_SPI_COMMAND_H #include class ISpiCommandHandler; /** * @brief APP 运行期 SPI 链路与命令路由模块。 * * 本类现在主要承担两件事: * - 维护 SPI0 从机的硬件链路(GPIO/SPI/DMA/EXTI) * - 将接收到的合法帧按 TYPE 注册式分发给 ISpiCommandHandler * * 具体命令处理逻辑不再放在这里,而是拆到 `device/app_spi_cmd_*.cpp`, * 通过 `registerHandler()` 注册进来,保持本模块可扩展。 */ class AppSpiCommand { public: /** @brief 初始化 SPI0 从机命令通道并注册默认命令处理器。 */ void init(); /** @brief 主循环轮询:打印延迟日志。 */ void poll(); /** @brief SPI0 中断处理入口。 */ void onInterrupt(); /** @brief CS 边沿中断处理入口。 */ void onCsExtiInterrupt(); /** * @brief 注册一个 SPI 命令处理器,用于 TYPE 路由。 * @param[in] handler 命令处理器指针,调用方需保证其生命周期有效。 */ void registerHandler(ISpiCommandHandler *handler); /** @brief 记录一条待输出日志,主循环统一打印。 */ void postLog(const char *msg); /** @brief 记录一条带 1 字节参数的待输出日志。 */ void postLogFmt(const char *fmt, uint8_t val); /** * @brief 将应答帧构建到指定发送缓冲区。 * @param[out] tx_buf 发送缓冲区。 * @param[in] tx_buf_size 发送缓冲区大小。 * @param[out] tx_len 构建完成后的帧长度。 * @param[in] rsp_type 响应类型。 * @param[in] payload 响应载荷。 * @param[in] payload_len 响应载荷长度。 */ void buildResponse(uint8_t *tx_buf, uint16_t tx_buf_size, uint16_t *tx_len, uint8_t rsp_type, const uint8_t *payload, uint16_t payload_len); static constexpr uint16_t kRxBufSize = 128U; static constexpr uint16_t kTxBufSize = 64U; static constexpr uint16_t kLogBufSize = 128U; private: static constexpr uint8_t kMaxCommands = 8U; volatile bool m_csActive = false; volatile uint8_t m_rxLen = 0U; uint8_t m_txLen = 0U; volatile uint8_t m_txPos = 0U; volatile bool m_logPending = false; uint8_t m_rxBuf[kRxBufSize] = {}; uint8_t m_txBuf[kTxBufSize] = {}; char m_logBuf[kLogBufSize] = {}; uint8_t m_commandCount = 0U; ISpiCommandHandler *m_commands[kMaxCommands] = {}; void configureGpio(); void configureSpi0(); void configureDma(); void configureExti(); void onCsAssert(); void onCsRelease(); void processCommand(); }; /** @brief 全局 SPI 命令总线实例。 */ extern AppSpiCommand AppSpiCommandBus; #endif /* DEVICE_APP_SPI_COMMAND_H */