feat(canfd): 添加通道使能控制和SPI握手信号支持
- 添加通道使能开关配置,通过sys/config.h中的CONFIG_CAN_CHx_ENABLE控制各通道 - 实现isChannelEnabled()方法用于查询通道使能状态 - 修正CAN1引脚映射配置,将RX/TX引脚对调并禁用重映射 - 修正错误计数器读取逻辑,REC字段从bit24开始提取而非bit8 - 修正busOff状态判断,使用CAN_ERR_BOERR标志位 - 调整滤波器配置时机,移到所有hardReset完成后防止共享寄存器被清零 - 在发送时增加总线健康检查,避免高错误计数时继续发送导致bus off - 添加SPI Ready握手信号(PB6)控制,改善主从机通信同步 fix(spi): 实现SPI命令处理中的READY信号握手协议 - 添加SPI Ready信号控制,PB6输出指示从机就绪状态 - CS下降沿立即拉低READY信号防主机抢跑 - 命令处理完成且无待处理命令时拉高READY信号 - 忽略无效事务后恢复READY信号避免超时 - 在繁忙期间保持READY信号低电平通知主机等待
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/**
|
||||
* @file app_spi_command.cpp
|
||||
* @brief APP 运行期 SPI 链路与命令路由实现。
|
||||
*
|
||||
@@ -237,6 +237,19 @@ void AppSpiCommand::configureGpio()
|
||||
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_5);
|
||||
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
|
||||
gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_15);
|
||||
|
||||
/* PB6 复用为 SPI Ready 握手输出,默认 HIGH(就绪),允许主机立刻发起首帧 */
|
||||
gpio_init(CONFIG_SPI_READY_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, CONFIG_SPI_READY_PIN);
|
||||
gpio_bit_set(CONFIG_SPI_READY_PORT, CONFIG_SPI_READY_PIN);
|
||||
}
|
||||
|
||||
void AppSpiCommand::setSpiReady(bool ready)
|
||||
{
|
||||
if (ready) {
|
||||
gpio_bit_set(CONFIG_SPI_READY_PORT, CONFIG_SPI_READY_PIN);
|
||||
} else {
|
||||
gpio_bit_reset(CONFIG_SPI_READY_PORT, CONFIG_SPI_READY_PIN);
|
||||
}
|
||||
}
|
||||
|
||||
void AppSpiCommand::configureSpi0()
|
||||
@@ -451,6 +464,13 @@ void AppSpiCommand::processCommand()
|
||||
/* 置位 TASK_SPI_LOG,唤醒主循环立刻打印日志 */
|
||||
TaskManager::set(1UL << TASK_SPI_LOG);
|
||||
}
|
||||
|
||||
/* 应答帧已就绪:若解析期间未再收到新帧(m_cmdPending 仍为 false),
|
||||
* 拉高 PB6 通知主机可发起下一笔事务;否则保持 LOW,等待下一轮
|
||||
* processCommand 完成后再翻高,避免主机在从机未就绪时抢跑。 */
|
||||
if (!m_cmdPending) {
|
||||
setSpiReady(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
@@ -494,6 +514,10 @@ void AppSpiCommand::onCsAssert()
|
||||
return;
|
||||
}
|
||||
m_csActive = true;
|
||||
/* CS 下降沿立即拉低 PB6:表示从机即将忙碌,
|
||||
* 防止主机在 onCsRelease 拉低 PB6 前抢跑发起下一笔 CS。
|
||||
* (若此帧被 shouldIgnoreTransaction 忽略,onCsRelease 会恢复 HIGH) */
|
||||
setSpiReady(false);
|
||||
m_rxLen = 0U;
|
||||
m_txPos = 0U;
|
||||
m_txActiveThisCs = false;
|
||||
@@ -554,6 +578,9 @@ void AppSpiCommand::onCsRelease()
|
||||
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
|
||||
}
|
||||
m_txActiveThisCs = false;
|
||||
/* 忽略事务(空轮询/残包)后恢复 PB6=HIGH,
|
||||
* 避免 PB6 卡 LOW 导致 ESP32 waitSpiReady 超时 */
|
||||
setSpiReady(true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -562,6 +589,8 @@ void AppSpiCommand::onCsRelease()
|
||||
m_txActiveThisCs = false;
|
||||
memset(m_txBuf, 0xFF, sizeof(m_txBuf));
|
||||
m_cmdPending = true;
|
||||
/* 拉低 PB6 通知主机:从机正忙,在主循环解析完前不要再发起 CS */
|
||||
setSpiReady(false);
|
||||
TaskManager::set(1UL << TASK_SPI_CMD_PROCESS);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user